数据结构学完了,总结一下排序。没有那种排序永远是最优的,各有千秋吧。
//插入排序 #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int * insert_sort(int a[], int n)//直接插入排序 { int i,j; for(i = 2; i <= n; i++) { if(a[i-1] > a[i]) { a[0] = a[i]; //复制为监视哨 a[i] = a[i-1]; //将a[i-1]后移 for(j = i-2; a[j] > a[0]; j--) a[j+1] = a[j];//将j+1与i-2之间的数向后移,j满足a[j+1] > a[0]而a[j] < a[0]; a[j+1] = a[0];//将待插入的a[i]插入a[j+1]处 } } return a; } //折半查找 int binsearch(int a[], int low, int high,int num) { while(low <= high) { int m = (low+high)/2; if(a[m] > num) high = m-1; else if(a[m] < num) low = m+1; } return low; } int * biInsertion_sort(int a[], int n)//折半插入排序 { int i,j; for(i = 2; i <= n; i++) { if(a[i-1] > a[i]) { a[0] = a[i]; int low = binsearch(a,1,i-1,a[i]);//通过折半查找找到a[i]插入的位置为a[low]; for(j = i-1; j >= low; j--) a[j+1] = a[j]; a[low] = a[0]; } } return a; } int * BubbleSort(int a[], int n)//起泡排序 { int i = n,j; int lastexchang; while(i > 1) { lastexchang = 1;//初始化最后一次交换位置 for(j = 1; j < i; j++) { if(a[j] > a[j+1]) { swap(a[j],a[j+1]); lastexchang = j;//更新最后一次交换位置 } } i = lastexchang;//lastexchang~n的关键字已经有序,下次从1~lastexchang-1 排序 } return a; } int main() { int a[110]; int n; scanf("%d",&n); for(int i = 1; i <= n; i++) scanf("%d",&a[i]); insert_sort(a,n);//对长度为n的数组从小到大直接插入排序 biInsertion_sort(a,n);//对长度为n的数组从小到大折半插入排序 BubbleSort(a,n);//对长度为n的数组从小到大起泡排序 for(int i = 1; i <= n; i++) printf("%d ",a[i]); return 0; }
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; //调整堆,从i节点开始从上往下调整,n为节点总数 void MaxHeapFixDown(int *a, int i, int n) { int j = 2*i+1;//i节点的子节点 int tmp = a[i]; while(j < n) { if(j + 1 < n && a[j+1] > a[j])//在节点i的左右孩子中找最大的 j++; if(tmp >= a[j])//如果tmp 均大于其左右孩子,说明已是合法堆 break; //否则就继续向下调整 a[i] = a[j]; i = j; j = 2*i+1; } a[i] = tmp; } //建立最大堆 void MakeMaxHeap(int *a, int n) { //对叶子节点来说,它们已是合法的最大堆了,所以只需从 n/2-1 开始向下调整就行了 for(int i = n/2-1; i >= 0; i--) { MaxHeapFixDown(a,i,n); } } //堆排序,先建立一个最大堆,那么a[0]肯定是节点中最大的,第一次将a[0]与a[n-1]交换, //再对a[0~n-2]调整堆,第二次将a[0]与a[n-2]交换,再对a[0~n-3]调整堆,重复这样的操作, //直到a[0]与a[1]交换,最后得到一个递增的有序序列。 void MaxHeapSort(int * a, int n) { MakeMaxHeap(a,n); for(int i = n-1; i >= 1; i--) { swap(a[i],a[0]); MaxHeapFixDown(a,0,i); } } int main() { int n,a[110]; scanf("%d",&n); for(int i = 0; i < n; i++) scanf("%d",&a[i]); MaxHeapSort(a,n); for(int i = 0; i < n; i++) printf("%d ",a[i]); printf("\n"); return 0; }
//归并排序 //划分问题,把序列分成元素个数尽量相等的两半 //递归求解,把两半元素分别排序 //合并问题,把两个有序表合并成一个 #include<stdio.h> #include<string.h> void merge_sort(int *a, int x, int y, int *t) { if(y - x > 1) { int m = x + (y-x)/2;//划分 int p = x, q = m, i = x; merge_sort(a,x,m,t);//递归求解 merge_sort(a,m,y,t);//递归求解 while(p < m || q < y) { if(q >= y || (p < m && a[p] <= a[q])) t[i++] = a[p++];//从左半数组复制到临时空间 else t[i++] = a[q++];//从右半数组复制到临时空间 } for(int i = x; i < y; i++) a[i] = t[i];//从辅助空间复制回a数组 } } int main() { int n; int a[110]; scanf("%d",&n); for(int i = 0; i < n; i++) scanf("%d",&a[i]); int * t = new int [n];//开辟辅助存储空间 merge_sort(a,0,n,t); for(int i = 0; i < n; i++) printf("%d ",a[i]); return 0; }
//快速排序的时间复杂度为O(nlogn) //若待排记录的初始状态为按关键字有序时,快速排序将蜕化为起泡排序,其时间复杂度为O(n2)。 #include<stdio.h> #include<string.h> //一趟快速排序 int Partition(int a[], int low, int high) { int t = a[low];// 枢轴 while(low < high) { while(low < high && a[high] >= t) high--;// 从右向左搜索 a[low] = a[high]; while(low < high && a[low] <= t) low++;// 从左向右搜索 a[high] = a[low]; } a[low] = t; return low; } void Qsort(int a[],int s, int t) { int pivotloc; if(s < t)// 长度大于1 { pivotloc = Partition(a,s,t); // 对 a[s..t] 进行一次划分 Qsort(a,s,pivotloc-1); // 对低子序列递归排序,pivotloc是枢轴位置 Qsort(a,pivotloc+1,t);// 对高子序列递归排序 } } int main() { int a[110],n; scanf("%d",&n); for(int i = 0; i < n; i++) scanf("%d",&a[i]); Qsort(a,0,n-1); for(int i = 0; i < n-1; i++) printf("%d ",a[i]); printf("%d\n",a[n-1]); return 0; }