数据结构几类排序的总结和完整代码 待续。。
一 插入排序
- 简单插入排序
- 希尔排序
二 快速排序
快排是冒泡排序的改进,每做一次排序可以确定一个数最终的位置p,同时把所有小于这个数的放在它左边,小于这个数的放在它后面。再递归地进行p左边部分和p右边部分的排序就可以了。
代码:
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 5 int a[100002],count1=0,n; 6 7 int each_sort(int low,int high) 8 { 9 int temp=a[low]; 10 while(low<high) 11 { 12 while(low<high&&a[high]>=temp)//找到high指向的<temp的值 一到前面来 13 high--; 14 a[low]=a[high]; 15 while(low<high&&a[low]<=temp)// 找到low指向的temp的值 移到后面去 16 low++; 17 a[high]=a[low]; 18 } 19 a[low]=temp; 20 return low; 21 } 22 23 24 void Qsort(int low,int high) 25 { 26 int position; 27 if(low<high) 28 { 29 position=each_sort(low,high); 30 Qsort(low,position-1); 31 Qsort(position+1,high); 32 } 33 } 34 35 void in() 36 { 37 printf("输入要排序列的个数:n\n"); 38 scanf("%d",&n); 39 printf("依次输入要排的n个数\n"); 40 for(int i=0; i<n; i++) 41 scanf("%d",&a[i]); 42 } 43 44 void out() 45 { 46 printf("\n结果:\n"); 47 for(int i=0; i<n; i++) 48 printf("%d ",a[i]); 49 printf("\n"); 50 } 51 52 int main() 53 { 54 while(1) 55 { 56 in(); 57 Qsort(0,n-1); 58 out(); 59 } 60 return 0; 61 }
三 选择排序
每次在i...n这段中选一个最小的记录放在i位置(n为序列总长度,i为1遍历到n的值)。
- 简单选择排序
1 #include<iostream> 2 #include<cstdio> 3 #define maxx 9999999 4 using namespace std; 5 6 int a[100002],count1=0; 7 int n; 8 9 void Qsort() 10 { 11 for(int i=1; i<=n; i++) 12 { 13 int minn=i; 14 for(int j=i+1; j<=n; j++) 15 if(a[minn]>a[j]) 16 minn=j; 17 swap(a[i],a[minn]); 18 } 19 } 20 21 void in() 22 { 23 printf("输入要排序列的个数:n\n"); 24 scanf("%d",&n); 25 printf("依次输入要排的n个数\n"); 26 for(int i=1; i<=n; i++) 27 scanf("%d",&a[i]); 28 } 29 30 void out() 31 { 32 for(int i=1; i<=n; i++) 33 printf("%d ",a[i]); 34 printf("\n"); 35 36 } 37 38 int main() 39 { 40 while(1) 41 { 42 in(); 43 Qsort(); 44 out(); 45 } 46 return 0; 47 }
- 树形选择排序(锦标赛排序) :简单选择排序每一趟平均的比较次数是n/2,其中很多次都是重复的导致效率较低,树形选择排序则改善了这个问题,每一趟的平均比较次数是logn。讲要排序的n个数两两比较,其中(n+1)/2个较小者再两两比较,如此重复知道选出了最小的关键字为止,选择次小,只要把最小的关键字的叶子节点的值改成无限大,再和其左(右)兄弟进行比较,修改从叶子节点到根节点的路径上的值)
- 堆排 树形选择排序缺点有辅助空间较多,最大值进行多次比较。二堆排序只需要一个记录大小的辅助空间。每个待排记录只需一个存储空间。
1 #include<iostream> 2 #include<cstdio> 3 #define maxx 9999999 4 using namespace std; 5 6 int a[100002],count1=0; 7 int n; 8 9 void adjust(int s,int n) 10 { 11 int i,temp=a[s],temps=s; 12 for( i=s*2; i<=n; i=i*2) 13 { 14 if(i<n&&a[i]>a[i+1]) 15 i++; 16 if(i<=n&&a[i]>a[s]) 17 break; // (若求的是大顶堆)当a[s]值比s的左右兄弟都大, 则不需要向下调整了 18 a[s]=a[i]; // s和s的左右兄弟里最大的是第i个(i!=s) 19 s=i; 20 } 21 a[s]=temp ; 22 } 23 24 void Qsort() 25 { 26 for(int i=n/2; i>0; i--) 27 adjust(i,n); //从最后一个非叶子结点开始,将他调整为大顶堆 28 for(int i=n; i>1; i--) 29 { 30 swap(a[1],a[i]); //a[1]为以选出的最大值 和a[i]交换 31 adjust(1,i-1); //对前i-1筛选,调整为大顶堆 32 } 33 printf("\n"); 34 } 35 36 void in() 37 { 38 printf("输入要排序列的个数:n\n"); 39 scanf("%d",&n); 40 printf("依次输入要排的n个数\n"); 41 for(int i=1; i<=n; i++) 42 scanf("%d",&a[i]); 43 } 44 45 void out() 46 { 47 for(int i=n; i>=1; i--) 48 printf("%d ",a[i]); 49 printf("\n"); 50 51 } 52 53 int main() 54 { 55 while(1) 56 { 57 in(); 58 Qsort(); 59 out(); 60 } 61 return 0; 62 }
四 归并排序
2-路归并排序时典型的分治算法,归并的含义是:将两个有序序列合成一个有序序列。用递归的写法可以很直观的表达
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 5 int a[100002],count1=0,n; 6 int b[100002]; 7 8 void Merge(int s,int t,int m) 9 { 10 int i,k,j; 11 for(int i=s;i<=t;i++) 12 b[i]=a[i]; //把s...t段的a 拷贝给b 13 for(k=s,j=m+1,i=s;i<=m&&j<=t;k++) 14 { 15 if(b[i]<b[j]) a[k]=b[i++]; 16 else a[k]=b[j++]; 17 } 18 while(i<=m) 19 a[k++]=b[i++];// 剩下的b[i....m]复制到a中 20 while(j<=t) 21 a[k++]=b[j++];// 剩下的b[j....t]复制到a中 22 23 } 24 25 void Msort(int s,int t) 26 { 27 if(s<t) 28 { 29 int mid=(s+t)/2; 30 Msort(s,mid); 31 Msort(mid+1,t); 32 Merge(s,t,mid);// 此时s..mid 和 mid+1..t段都是有序的了,再合并这两部分为一个有序的 33 } 34 } 35 36 37 void in() 38 { 39 printf("输入要排序列的个数:n\n"); 40 scanf("%d",&n); 41 printf("依次输入要排的n个数\n"); 42 for(int i=0; i<n; i++) 43 scanf("%d",&a[i]); 44 } 45 46 void out() 47 { 48 printf("\n结果:\n"); 49 for(int i=0; i<n; i++) 50 printf("%d ",a[i]); 51 printf("\n"); 52 } 53 54 int main() 55 { 56 while(1) 57 { 58 in(); 59 Msort(0,n-1); 60 out(); 61 } 62 return 0; 63 }
五 基数排序