头文件:
#include <iostream> //1插入类的排序: //希尔排序:取增量d1的分为一组,共分成d1组分别进行插入排序,然后每组对应元素放在一起,然后取d2...知道d=1 //希尔排序的代码可以近乎看成把1换成dk /*我们简单处理增量序列:增量序列d = {n/2 ,n/4, n/8 .....1} n为要排序数的个数 即:先将要排序的一组记录按某个增量d(n/2,n为要排序数的个数)分成若干组子序列,每组中记录的下标相差d.对每组中全部 元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。继续不断缩小增量直至 为1,最后使用直接插入排序完成排序。*/ //时间复杂度 O(n^3/2) 不稳定 void ShellSort(int a[], int n){ int i, j, dk; for(dk = n/2; dk > 0; dk /= 2){ for(i = dk; i <= n; i++){ if(a[i] < a[i-dk]){ a[0] = a[i]; for(j = i-dk; a[j]>a[0] && j>=0; j -= dk) a[j+dk] = a[j]; a[j+dk] = a[0]; } } } } //直接插入排序:将第一个数据看成有序表,将后面的数据一次插入表中 //时间复杂度 O(n^2) 稳定 void InsertSort(int a[], int n){ int i, j; for(i = 1; i <= n; i++){ if(a[i] < a[i-1]){ //若插入的第i个数大于它的前一个数i-1,就直接插入再最后,如果小于,就移动有序表插入 a[0] = a[i]; //设置为哨兵,作用是用于暂时存放要插入的数 for(j = i-1; a[j]>a[0] && j>=0; j--)//从要插入数i的前一个数i-1开始,若比i大,就后移一位 a[j+1] = a[j]; a[j+1] = a[0]; //找到真确位置,将要插入数放在第j个数后面 } } } //2归并类排序: /*归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表, 即把待排序序列分为若干个子序列,每个子序列是有序的。 然后再把有序子序列合并为整体有序序列。*/ //时间复杂度 O(nlogn) 稳定 //合并两个已经排好顺序的数组 void Merge(int a[], int start, int mid, int end, int *temp){ int i = start, j = mid+1, k = 0;//start到mid位数组1,mid+1到end为数组2 while(i<=mid && j<=end) //从两个数组最低位开始比较,数值小的存入临时数组 temp[k++] = (a[i] <= a[j]) ? a[i++] : a[j++]; while(i <= mid) //总有一个数组先比较完,所以处理剩下数组的元素 temp[k++] = a[i++]; while(j <= end) temp[k++] = a[j++]; k = 0; //下面将排完序的临时数组里的数拷贝到原数组里 for(i = start; i <= end; i++) a[i] = temp[k++]; } //用分治法进行二路归并 void MergeSort(int a[], int start, int end, int *temp){ if(start < end){ //当数组至少有两个元素时,进行二路归并 int mid = (start+end)/2; MergeSort(a, start, mid, temp); MergeSort(a, mid+1, end, temp); Merge(a, start, mid, end, temp); } } //3交换类排序: //快速排序 //时间复杂度 O(nlogn) 不稳定 void QuickSort(int a[], int n){ int low, high, p, t; if(n < 2)//只有一个数,不用交换 return; p = a[n/2]; //p取数组a的中间的数 for(low = 0, high = n-1;; low++, high--){ //从p的两边开始排序 while(p > a[low]) //将小于p的数放在左边,大于p的数放在p的右边 low++; while(p < a[high]) high--; if(low >= high) break; t = a[low]; //如果p左边的数比p右边的那个数大,把p左右两边数交换一下 a[low] = a[high]; a[high] = t; } QuickSort(a, low); //第一个递归调用处理数组的前部分,a对应的是数组的首地址,low是指对应的元素个数 QuickSort(a+low, n-low);//第二个递归调用处理数组后部分,a + low指的当然是首地址加偏移地址,n-low就是p后面剩下的元素个数 } //冒泡排序 //时间复杂度 O(n^2) 稳定 void BubbleSort(int a[], int n){ for(int i = 1; i <= n; i++) //每一趟结束都把一个最大的数放到最下面 for(int j = 1; j <= n-i; j++) if(a[j] > a[j+1]){ int t = a[j]; a[j] = a[j+1]; a[j+1] = t; } } //4选择类排序: /*堆排序:初始时把要排序的n个数的序列看作是一棵顺序存储的二叉树(一维数组存储二叉树), 调整它们的存储序,使之成为一个堆,将堆顶元素输出, 得到n 个元素中最大(或最小)的元素,这时堆的根节点的数最大(或者最小)。 然后对前面(n-1)个元素重新调整使之成为堆,输出堆顶元素,得到n 个元素中次小(或次大)的元素。 依此类推,直到只有两个节点的堆,并对它们作交换,最后得到有n个节点的有序序列*/ //堆排序:树形选择排序,将带排序记录看成完整的二叉树,第一步:建立初堆,第二步:调整堆 //时间复杂度 O(nlogn) 不稳定 //第二步:调整堆 void HeapAdjust(int a[], int s, int n){ //调整为大根堆,从大到小 int rc = a[s];//rc根节点,s第一个节点,n节点数 for(int j = 2*s; j <= n; j *= 2){ if(j<n && a[j]<a[j+1])//判断左右子数大小 j++; if(rc >= a[j])//直到找到比第一个节点大的数 break; a[s] = a[j]; s = j; } a[s] = rc; } //第一步:建初堆 void CreatHeap(int a[], int n){ //大根堆 for(int i = n/2; i > 0; i--) HeapAdjust(a, i, n); } //整合 void HeapSort(int a[], int n){ CreatHeap(a, n);//第一步建堆 for(int i = n; i > 1; i--){ //堆顶与最后一个元素互换 int x = a[1]; a[1] = a[i]; a[i] = x; HeapAdjust(a, 1, i-1); } } //简单选择排序:遍历一次找到最小与第一个元素互换位置,再从第二个元素开始遍历找到最小与第二个元素互换位置... //时间复杂度 O(n^2) 稳定 void SelectSort(int a[], int n){ for(int i = 1; i < n; i++){ //第一趟共比较n-1次 int k = i; //k总是指向最小的那个数的下标,开始认为第一个数最小,然后把最小的数往上放 for(int j = i+1; j <= n; j++) //从个第二个数开始循环找出这组数中最小数的下标,并把它赋值给k if(a[j] < a[k]) k = j; if(k != i){ //若果最小的那个数不是开始排序的第一个数,那么就把最小的那个数和开始排序的第一个数交换 int t = a[i]; a[i] = a[k]; a[k] = t; } } }主函数:
#include <iostream> #include<iomanip> #include "Sort.h" #define Max 101 using namespace std; int main(){ cout << endl << endl << endl; cout <<setw(45) << "******************"; cout << "综" <<setw(10) << "合"<< setw(10) << "排" << setw(10) << "序"; cout << "****************"; cout << endl << endl << endl; cout <<setw(55) << "****************************"; cout << "菜" << setw(10) <<"单"; cout << "**************************"; cout << endl << endl; cout <<" " << setw(93) << "--------------------------------------------------------------------"; cout << endl; cout << " " << setw(40) << "+ 归并排序----0" << setw(53) << "+" << endl; cout << " " << setw(26) << "+" << setw(67) << "+" << endl;; cout <<" " << setw(40) << "+ 希尔排序----1" << setw(50) << "直接插入排序----2" << setw(3) << "+" << endl; cout << " " << setw(26) << "+" << setw(67) << "+" << endl; cout <<" " << setw(40) << "+ 快速排序----3" << setw(46) << "冒泡排序----4" << setw(7) << "+" << endl; cout << " " << setw(26) << "+" << setw(67) << "+" << endl; cout <<" " << setw(38) << "+ 堆排序----5" << setw(52) << "简单选择排序----6" << setw(3) << "+" << endl; cout << " " << setw(26) << "+" << setw(67) << "+" << endl; cout <<" " << setw(93) << "--------------------------------------------------------------------"; cout << endl << endl; cout <<setw(55) << "*****************************"; cout << "退出程序----7"; cout << "**************************" << endl << endl; cout << "(注意:选择排序算法时输入对应的编号即可)" << endl; cout << endl; int num, a[Max]; while(scanf("%d", &num) != EOF){ for(int i = 1; i <= Max-1; i++){ a[i] = rand(); } if(num == 0){ cout << "您选择了归并排序:" << endl << endl; int temp[Max-1] = {-1}; //临时数组,作为参数传递,避免每次在merge中分配临时数组 MergeSort(a, 1, Max-1, temp); cout << "排序后:" << endl; for(int i = 1; i <= Max-1; i++) cout << left << setw(6) << a[i]; cout << endl << endl; } if(num == 1){ cout << "您选择了希尔排序:" << endl << endl; ShellSort(a, Max-1); cout << "排序后:" << endl; for(int i = 1; i <= Max-1; i++) cout << left << setw(6) << a[i]; cout << endl << endl; } if(num == 2){ cout << "您选择了直接插入排序:" << endl << endl; InsertSort(a, Max-1); cout << "排序后:" << endl; for(int i = 1; i <= Max-1; i++) cout << left << setw(6) << a[i]; cout << endl << endl; } if(num == 3){ cout << "您选择了快速排序:" << endl << endl; QuickSort(a, Max-1); cout << "排序后:" << endl; for(int i = 1; i <= Max-1; i++) cout << left << setw(6) << a[i]; cout << endl << endl; } if(num == 4){ cout << "您选择了冒泡排序:" << endl << endl; BubbleSort(a, Max-1); cout << "排序后:" << endl; for(int i = 1; i <= Max-1; i++) cout << left << setw(6) << a[i]; cout << endl << endl; } if(num == 5){ cout << "您选择了堆排序:" << endl << endl; HeapSort(a, Max-1); cout << "排序后:" << endl; for(int i = 1; i <= Max-1; i++) cout << left << setw(6) << a[i]; cout << endl << endl; } if(num == 6){ cout << "您选择了简单选择排序:" << endl << endl; SelectSort(a, Max-1); cout << "排序后:" << endl; for(int i = 1; i <= Max-1; i++) cout << left << setw(6) << a[i]; cout << endl << endl; } if(num == 7){ cout << "您已退出程序!"; return 0; } } return 0; }