查找排序的应用实验.docx
- 文档编号:30171452
- 上传时间:2023-08-05
- 格式:DOCX
- 页数:20
- 大小:41.43KB
查找排序的应用实验.docx
《查找排序的应用实验.docx》由会员分享,可在线阅读,更多相关《查找排序的应用实验.docx(20页珍藏版)》请在冰豆网上搜索。
查找排序的应用实验
淮海工学院计算机科学系
实验报告书
课程名:
《数据结构》
题目:
查找、排序的应用实验
班级:
软件081班
学号:
*********
姓名:
XX
排序、查找的应用实验报告要求
1目的与要求:
1)查找、排序是日常数据处理过程中经常要进行的操作和运算,掌握其算法与应用对于提高学生数据处理能力和综合应用能力显得十分重要。
2)本次实验前,要求同学完整理解有关排序和查找的相关算法和基本思想以及种算法使用的数据存储结构;
3)利用C或C++语言独立完成本次实验内容或题目,程序具有良好的交互性(以菜单机制实现实验程序的交互运行)和实用性;
4)本次实验在机房现场验收和平分,希望同学们认真对待,并按时完成实验任务;
5)认真书写实验报告(包括程序清单及相关实验数据与完整运行结果),并按时提交。
2实验内容或题目
题目:
对记录序列(查找表):
{55,13,23,72,109,67,2,78,13}分别实现如下操作:
1)顺序查找;
2)分别使用直接插入排序、冒泡排序、快速排序对原纪录序列进行排序;
3)对排好序的纪录序列表进行折半查找;
4)利用原纪录序列建立一颗二叉排序树,并在其上实现特定关键字值结点的查找;
5)按照“除留余数法”哈希构造函数和线性探测再散列的冲突处理方法创建表长为m=11的哈希表;
6)实现5)创建哈希表上的查找。
3实验步骤与源程序
#include
#include
#include
#defineLIST_SIZE20
#defineTRUE1
#defineFALSE0
#defineSUCCESS1
#defineUNSUCCESS-1
#defineMAX100
typedefcharKeyType;
typedefintOtherType;
typedefstruct
{KeyTypekey;
OtherTypeother_data;
}RecordType;
typedefstruct
{RecordTyper[LIST_SIZE+1];/*r[0]为工作单元*/
intlength;
}RecordList;
//二叉排序树的创建与查找
#defineENDKEY0
typedefstructnode
{
KeyTypekey;/*关键字的值*/
structnode*lchild,*rchild;/*左右指针*/
}BSTNode,*BSTree;
/*哈希表的创建*/
typedefstruct
{
intkey;
intflag;//falg=1时表示有关键字,=0时表示没有关键字
}Elemtype;
typedefstruct
{
Elemtype*elem;//动态分配的哈希表的首地址
intsizeindex;//hashsize[sizeindex]为当前容量
intcount;//当前数据元素个数
}HashTable;
/*顺序查找*/
voidSeqSearch(RecordListl,KeyTypek)
/*在顺序表l中顺序查找其关键字等于k的元素,若找到,则函数值为该元素在表中的位置,否则为0*/
{
inti;
l.r[0].key=k;
i=l.length;
while(l.r[i].key!
=k)i--;
if(i>=1)
{
printf("该元素k所在的位置是:
");
printf("%d",i);
}
else
printf("该元素不存在");
}
//直接插入排序
voidInsSort(RecordTyper[],intlength)
/*对记录数组r做直接插入排序,length为数组中待排序记录的数目*/
{
inti,j;
for(i=2;i<=length;i++)
{
r[0]=r[i];/*将待插入记录存放到监视哨r[0]中*/
j=i-1;
while(r[0].key { r[j+1]=r[j]; j=j-1; } r[j+1]=r[0];/*将待插入记录插入到已排序的序列中*/ } }/*InsSort*/ /*冒泡排序*/ voidBubbleSort(RecordTyper[],intlength) /*对记录数组r做冒泡排序,length为数组的长度*/ { intx,i,n,change,j; n=length;change=TRUE; for(i=1;i<=n-1&&change;++i) { change=FALSE; for(j=1;j<=n-i;++j) if(r[j].key>r[j+1].key) { x=r[j].key; r[j]=r[j+1]; r[j+1].key=x; change=TRUE; } } } //快速排序 intPartition(RecordList&L,intlow,inthigh)//Partition()sub-function {intpivotkey; L.r[0]=L.r[low]; pivotkey=L.r[low].key; while(low {while(low --high; L.r[low]=L.r[high]; while(low ++low; L.r[high]=L.r[low]; } L.r[low]=L.r[0]; return(low); }//Partition()end voidQsort(RecordList&L,intlow,inthigh)//Qsort()sub-function {intpivotloc; if(low {pivotloc=Partition(L,low,high); Qsort(L,low,pivotloc-1); Qsort(L,pivotloc+1,high); } } voidQuickSort(RecordList&L)//QuickSort()sub-function {Qsort(L,1,L.length);//callQsort() } /*对排好的序进行折半查找算法*/ voidBinSrch(RecordListl,KeyTypek) /*在有序表l中折半查找其关键字等于k的元素,若找到,则函数值为该元素在表中的 位置*/ { intlow,high,mid; low=1; high=l.length;/*置区间初值*/ while(low<=high) { mid=(low+high)/2; if(k==l.r[mid].key) { printf("找到该元素,其位置为%d",mid); break; }/*找到待查元素*/ else if(k high=mid-1;/*未找到,则继续在前半区间进行查找*/ else low=mid+1;/*继续在后半区间进行查找*/ } if(low>high)printf("没有找到该元素"); } voidInsertBST(BSTree*bst,KeyTypekey) /*若在二叉排序树中不存在关键字等于key的元素,插入该元素*/ { BSTrees; if(*bst==NULL)/*递归结束条件*/ { s=(BSTree)malloc(sizeof(BSTNode));/*申请新的结点s*/ s->key=key; s->lchild=NULL; s->rchild=NULL; *bst=s; } else if(key<(*bst)->key) InsertBST(&((*bst)->lchild),key);/*将s插入左子树*/ else if(key>(*bst)->key) InsertBST(&((*bst)->rchild),key);/*将s插入右子树*/ } voidCreateBST(BSTree*bst) /*从键盘输入元素的值,创建相应的二叉排序树*/ { KeyTypekey; *bst=NULL; scanf("%d",&key); while(key! =ENDKEY)/*ENDKEY为自定义常量*/ { InsertBST(bst,key); scanf("%d",&key); } } voidPreOrder(BSTreeroot) /*先序遍历二叉树,root为指向二叉树根结点的指针*/ { if(root! =NULL) { printf("%d",root->key);/*输出结点*/ PreOrder(root->lchild);/*先序遍历左子树*/ PreOrder(root->rchild);/*先序遍历右子树*/ } } BSTreeSearchBST(BSTreebst,KeyTypekey) /*在根指针bst所指二叉排序树中,递归查找某关键字等于key的元素,若查找成功,返回指向该元素结点指针,否则返回空指针*/ { if(! bst) returnNULL; else if(bst->key==key) returnbst;/*查找成功*/ else if(bst->key>key) returnSearchBST(bst->lchild,key);/*在左子树继续查找*/ else returnSearchBST(bst->rchild,key);/*在右子树继续查找*/ } BSTNode*DelBST(BSTreet,KeyTypek)/*在二叉排序树t中删去关键字为k的结点*/ { BSTNode*p,*f,*s,*q; p=t; f=NULL; while(p)/*查找关键字为k的待删结点p*/ { if(p->key==k)break;/*找到则跳出循环*/ f=p;/*f指向p结点的双亲结点*/ if(p->key>k) p=p->lchild; else p=p->rchild; } if(p==NULL)returnt;/*若找不到,返回原来的二叉排序树*/ if(p->lchild==NULL)/*p无左子树*/ { if(f==NULL) t=p->rchild;/*p是原二叉排序树的根*/ else if(f->lchild==p)/*p是f的左孩子*/ f->lchild=p->rchild;/*将p的右子树链到f的左链上*/ else/*p是f的右孩子*/ f->rchild=p->rchild;/*将p的右子树链到f的右链上*/ free(p);/*释放被删除的结点p*/ } else/*p有左子树*/ { q=p; s=p->lchild; while(s->rchild)/*在p的左子树中查找最右下结点*/ {q=s; s=s->rchild; } if(q==p) q->lchild=s->lchild;/*将s的左子树链到q上*/ else q->rchild=s->lchild; p->key=s->key;/*将s的值赋给p*/ free(s); }returnt; }/*DelBST*/ /*建立哈希表*/ intCreatHashTable(HashTable&H,intm) { inti,keys,p,len; H.elem=(Elemtype*)malloc(MAX*sizeof(Elemtype)); H.sizeindex=MAX;//初始存储容量 H.count=0; printf("请输入该组关键字的个数: "); scanf("%d",&m); printf("请输入表长len: "); scanf("%d",&len); H.sizeindex=len; for(i=0;i { H.elem[i].flag=0; } printf("请输入该组关键字: "); for(i=0;i { scanf("%d",&keys); p=keys%m; while(H.elem[p].flag==1)//处理冲突 { intd=1; p=(p+d)%m; d++; } H.elem[p].key=keys; H.elem[p].flag=1; H.count++; } for(intj=H.count;j H.elem[j].key=0; printf("哈希表创建完毕! \n"); printf("下标关键字\n"); for(i=0;i { printf("%d",i); printf("%d",H.elem[i].key); printf("\n"); } returnSUCCESS; } voidSearchHashTable(HashTableH) {intkeys,p; printf("请输入您要查找的关键字: \n"); scanf("%d",&keys); for(inti=0;i { if(keys==H.elem[i].key)//p是找到的关键字的下标 { p=i; } } if(p>-1&&p { printf("查找成功! \n"); printf("该关键字在哈希表中的下标为: %d\n",p); } else printf("查找失败,表中无此关键字! \n"); } voidmain() { inti,j,select,a,flag=1,m=0; printf("1记录序列\n2进行顺序查找\n3进行直接排序\n4进行冒泡排序\n5进行快速排序\n6对排好序的纪录序列表进行折半查找\n7利用原纪录序列建立一颗二叉排序树,并在其上实现特定关键字值结点的查找\n8建立哈希表,并对其进行查找\n9退出\n"); RecordTyper[20]; BSTreebst,result,T; RecordListL,Q; intlength,k,low; while(flag) { printf("请选择: "); scanf("%d",&a); switch(a) { case1: printf("请输入待排序记录的长度: ");//交互创建纪录表 scanf("%d",&length); for(i=1;i<=length;i++) { printf("请输入第%d个记录元素: ",i); fflush(stdin); scanf("%d",&j); r[i].key=j; } printf("你输入的各元素为: "); for(i=1;i<=length;i++) printf("%d",r[i].key); printf("\n");break; case2: printf("请输入你要查找的元素k: "); fflush(stdin); scanf("%d",&k); L.length=length; for(i=1;i<=L.length;i++) { L.r[i]=r[i]; } SeqSearch(L,k); printf("\n"); break; case3: InsSort(r,length); printf("按直接排序后各元素为: "); for(i=1;i<=length;i++) printf("%d",r[i].key); printf("\n");break; case4: BubbleSort(r,length); printf("按冒泡排序后各元素为: "); for(i=1;i<=length;i++) printf("%d",r[i].key); printf("\n"); break; case5: L.length=length; for(i=1;i<=L.length;i++) { L.r[i]=r[i]; } QuickSort(L); printf("进行快速排序后各元素为: "); for(i=1;i<=L.length;i++) printf("%d",L.r[i].key); printf("\n"); break; case6: InsSort(r,length); L.length=length; for(i=1;i<=L.length;i++) { L.r[i]=r[i]; } printf("请输入要查找的元素: "); scanf("%d",&k); BinSrch(L,k); printf("\n"); break; case7: intk; printf("建立二叉排序树,请输入序列(以0结束): \n"); CreateBST(&T); printf("先序遍历输出序列为: "); PreOrder(T); printf("\n请输入要查找的元素: "); fflush(stdin); scanf("%d",&k); result=SearchBST(T,k); if(result! =NULL) printf("存在要查找的元素为%d\n",result->key); else printf("未找到! \n"); result=DelBST(T,k); //getch(); break; case8: HashTableH; CreatHashTable(H,m); SearchHashTable(H); break; case9: flag=0; } } } 4测试数据与实验结果(可以抓图粘贴) 先记录序列,再进行顺序查找,之后分别进行直接排序、冒泡排序、快速排序,如图: 对已排好的序进行折半查找,并建立二叉树,进行相应查找,如图: 最后按照“除留余数法”哈希构造函数和线性探测再散列的冲突处理方法创建表长为m=11的哈希表,并进行查找,如图: 5结果分析与实验体会 这次的实验是查找与排序的综合,查找主要就用了顺序查找、折半查找法,但折半查找要是顺序表。 顺序查找法的特点是,用所给关键字与线性表中各元素的关键字逐个比较,知道成功或失败,存储结构通常为顺序结构,也可以是链式结构。 对记录表进行排序,该程序中主要有直接排序、冒泡排序与快速排序,其实还有个希尔排序等等,但他们的时间复杂度各不相同。 最后的哈希表相对前面比较难,主要是因为书上没相应的程序,只能自己写。 老师要求表长为11,但给出的元素就只有9个,哈希表中就会有空元素,这里我把空元素就定义为了0.哈希表的构建方法有很多,包括: 数字分析法、平方取中法、分段叠加法、除留余数法与伪随机法。 当然,用不同飞方法,各元素存储的位置就各不相同。 这次的比较有综合性的实验相对而言不是太难,老师有给出的相应的部分程序,但我自己还会认真看懂的。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 查找 排序 应用 实验