1、数据结构实验排序数据结构实验报告课程名称 数据结构 成 绩 实验项目 排序 指导教师 学生姓名 学号 班级专业 实验地点 实验日期 2012 年 12 月 29日排序一、实习目的 熟悉几种典型的排序方法,并对各种算法的特点、使用范围和效率有进一步的了解。二、实例排序是计算机科学中非常基本且使用频繁的运算,在计算机系统软件和应用软件中都有广泛的应用。下面给出的是冒泡排序、快速排序的实现与比较。/* 源程序的头文件 sort.h */void getrandat(Data ary,int count) /* 产生一批随机数,准备排序 */ long int a=100001; int i; for
2、(i=0;icount;i+) a=(a*125)%2796203; aryi.key=(int)a; /* getrandat */void prdata(Data ary,int count) /* 输出数据的函数 */ int i; char ch; printf(“n”); for(i=0;icount;i+) printf(“%6d”,aryi.key); printf(“n”); printf(“nn 打回车键,结束显示。“); ch=getch(); /* prdata */两种排序方法的比较源程序/* sortcmp.c */#include #include #define
3、MAX 1000 /* 数组最大界限 */typedef int ElemType; /* 关键字的类型 */typedef struct ElemType key; int shu; /* 其它属性域 */ Data; /* 一个纪录的结构体类型 */Data arMAX,brMAX; typedef struct int lo,hi; Selem; /* 栈的元素结构体类型 */typedef struct Selem elemMAX; /* 一维数组子域 */ int top; /* 栈顶指针子域 */ SqStack; /* 栈的顺序结构体类型 */SqStack s1;/* 函数声明
4、 */void bubble(Data ary,int n);void getrandat(Data ary,int count) ; /* 产生一批随机数,准备排序 */void qksort(Data ary,int n);void hoare(Data ary,int l,int h);void init_s(SqStack *s); void push(SqStack *s,Selem e); /* 进栈一个元素 */Selem pop(SqStack *s);void prdata(Data ary,int count); /* 输出数据的函数 */int empty(SqStack
5、 s);/* 主函数 */void main() int k,n,j; j; char ch; do printf(nnn); printf(nn 1. 产生一批随机数准备排序 ); printf(nn 2. 一般情况的起泡排序); printf(nn 3. 有序情况的起泡排序); printf(nn 4. 一般情况的快速排序); printf(nn 5. 有序情况的快速排序); printf(nn 6. 结束程序运行); printf(n=); printf(n 请输入您的选择 (1,2,3,4,5,6); scanf(%d,&k); switch(k) case 1: printf(the
6、 number of datas:); /* 输入数据个数 */ scanf(%d,&n); getrandat(ar,n); /*产生n个随机数 */ for(j=0;jn;j+)brj=arj; /* 保留复原始数据 */ prdata(ar,n); break; case 2: for(j=0;jn;j+) arj=brj; /* 恢复原始数据 */ bubble(ar,n); /* 对n个数据起泡排序 */ prdata(ar,n); /* 排序后输出 */ break; case 3: bubble( ar,n); /* 有序情况的起泡排序 */ prdata(ar,n); brea
7、k; case 4: for(j=0;j=1 & k6); printf(n 再见!); printf(n 打回车键,返回。); ch=getchar(); /* main */* 起泡排序 */void bubble(Data ary,int n) int i,j,tag; Data x; i=0; do tag=0; for(j=0;jaryj+1.key) x=aryj; aryj=aryj+1; aryj+1=x; tag=1; i+; while( in-1 & tag=1); /* bubble */* 快速排序非递归算法 */void qksort(Data ary,int n)
8、 int low,high,i,tag; Selem x,y; init_s( &s1); /* 初始化一个空栈 */ low=0; high=n-1; tag=1;do while(lowhigh) i=hoare(ary,low,high); /* 调用一趟快速排序 */ x.lo= i+1; x.hi=high; push(&s1,x); high=i-1; if(empty()=0) tag=0; else y=pop(s1); low=y.lo; high=y.hi; while(tag=1); /* qksort */* 一趟快速排序 */int hoare(int ary,int
9、 l,int h) int i,j; Data x; i=l; j=h; x=aryl; do while(i=x) j-; if (ij) aryi=aryj; i+; while(ij)&aryi=x) i+; if(ij) aryj=aryi; j-; while(itop=0; /* init_s */; /* 进栈一个元素 */void push(SqStack *s,Selem e) if(s-top=MAX-1)printf(n stack Overflow!n); else s-top+; s-elems-top=e; /* push */* 出栈一个元素 */Selem po
10、p(SqStack *s) init_s( &s1); Selem e; if(s-top=0) printf(n satck Empty!n); e.lo=-1; e.hi=-1; else e=s-elems-top; s-top-; return(e); /* pop */void getrandat(Data ary,int count) /* 产生一批随机数,准备排序 */ long int a=100001; int i; for(i=0;icount;i+) a=(a*125)%2796203; aryi.key=(int)a; /* getrandat */void prdat
11、a(Data ary,int count) /* 输出数据的函数 */ int i; char ch; printf(n); for(i=0;icount;i+) printf(%6d,aryi.key); printf(n); printf(nn 打回车键,结束显示。); ch=getchar(); /* prdata */ 本程序中,qksort用非递归实现快速排序,在这个函数里,调用了hoare函数,函数,hoare对arylh进行一趟快速排序,执行该函数后,将ary从下标i处分成左右两个分区,其中左分区中的数据均小于等于aryi.key,而右分区中的数据均大于等于aryi.key(li
12、h)。将右区尾指针(记录下标)保存入栈,对左区再调用hoare进行快速排序。另外,此处用到的栈与以前的栈结构稍有不同,(因为栈中同时要放进两个值),故操作也稍有不同。例:入栈时,要两个参数即右区首、尾指针组成的结构体变量入栈。快速排序的最坏情况亦即各元素已有序时,再进行快速排序,这种情况下,其实并不快,这种情况下的冒泡排序反而很快。可见算法的优劣并不是绝对的。快速排序适合于记录关键字无序的b 情况。排序因其应用广泛,所以人们在排序找方面的研究经久不衰。三、实习题1. 编写程序实现简单选择排序、堆排序(或归并排序),进行比较分析。算法设计如下:1 单选择排序法:#include#define M
13、AX 50/*输入数据操作*/void InputData(int list,int n) printf(请输入数据:); for(int i=0;in;i+) scanf(%d,&listi);/*输出数据操作*/void OutputData(int list,int n) printf(排序后的顺序:n); for(int k=0;kn;k+) printf(%5d,listk); printf(nn);/*简单选择排序操作*/void SelectSort(int list,int n) int i,j,k,temp; for(i=0;in;i+) k=i; for(j=i+1;jn;
14、j+) if(listjlistk) k=j; if(i!=k) temp=listi; listi=listk; listk=temp; OutputData(list,n);/*主函数*/void main() int num; int listMAX; printf(请输入系列表的长度:); scanf(%d,&num); InputData(list,num); SelectSort(list,num);程序运行输出界面如下:2 排序法#include/*交换函数*/void swap(int *x,int *y) int t; t=*x;*x=*y;*y=t;void HeapAdj
15、ust(int *a,int i,int size) /调整堆 int lchild=2*i; /i的左孩子节点序号 int rchild=2*i+1; /i的右孩子节点序号 int max=i; /临时变量 if(i=size/2) /如果i不是叶节点就不用进行调整 if(lchildamax) max=lchild; if(rchildamax) max=rchild; if(max!=i) swap(&ai,&amax); HeapAdjust(a,max,size); /避免调整之后以max为父节点的子树不是堆 void BuildHeap(int *a,int size) /建立堆
16、int i; for(i=size/2;i=1;i-) /非叶节点最大序号值为size/2 HeapAdjust(a,i,size); void HeapSort(int *a,int size) /堆排序 int i; BuildHeap(a,size); for(i=size;i=1;i-) swap(&a1,&ai); /交换堆顶和最后一个元素,即每次将剩余元素中的最大者放到最后面 HeapAdjust(a,1,i-1); /重新调整堆顶节点成为大顶堆 for(i=1;i=size;i+) printf(%5d,ai); void main() int size;int i; int a
17、100;a0=0; printf(请输入需排数字个数 ); scanf(%d,&size); printf(请输入对应的数字:); for(i=1;i=size;i+) scanf(%d,&ai); printf(堆排序后为 ); HeapSort(a,size); printf(n); 程序输出运行界面如下:2. 编写程序实现简单插入排序、希尔排序(或基数排序),进行比较分析。算法设计如下:一:简单插入排序法 #include #include #define N 256void INSERTION_SORT(int aN,int m)int i,j,key,k; for(j=1;j=0&a
18、ikey) ai+1=ai; i=i-1; ai+1=key; printf(n使用(插入排序法)得到的新序列为:n); for(k=0;kj;k+) printf(%5d,ak);void main() int i,j,aN,k;printf(n请输入需要排的个数:); scanf(%d,&j); printf(n请输入对应的数:); for(i=0;ij;i+)scanf(%d,&ai); INSERTION_SORT(a,j); /调用插入排序法 printf(n) ;程序运行输出界面如下:四、实验结论排序时计算机程序设计中的一种重要操作,其目的是将一组“无序”的记录序列调整为“有序”的记录序列。根据排序过程中涉及的存储器的不同,排序分为内部排序和外部排序两类。所谓内部排序,是指待排序列完全存放在内存中进行的排序过程,适合不太大的元素序列。所谓外部排序,是指排序过程中还需要访问外存的排序过程,适合于待排序列记录数量较大,而不能完全放入内存的元素序列,排序过程中数据在内存和外村之间需要多次移动。五、实验总结通过此次实验,我了解了各种排序的基本方法,明白了各种排序方法的基本思想 ,并且排序算法的实现方法中包含了丰富的程序设计技巧,比较经典的排序算法有插入排序、交换排序、选择排序、归并排序、堆排序和基数排序,这对于初学者而言提高软件设计能力帮助很大。
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1