#include<iostream>#include<string>usingnamespace std;/*-------------------- 插入排序 ----------------------
直接插入排序的两个性质:
- 在最好的情况(序列本身已是有序的)下时间代价为 O(n)
- 对于短序列,直接插入排序比较有效
shell 排序有效地利用了直接排序的这两个性质
-----------------------------------------------------*///插入排序算法(升序排列)template<classT>voidImprovedInsertSort(T Array[],int n){
T TempRecord;//临时变量for(int i =1; i < n;++i)//依次插入第 i 个记录{
TempRecord = Array[i];int j = i -1;//从 i 开始往前寻找记录 i 的正确位置while((j >=0)&&(TempRecord < Array[j]))//将那些大于等于记录 i 的记录后移{
Array[j +1]= Array[j];
j = j -1;}
Array[j +1]= TempRecord;//此时 j 后面就是记录 i 的正确位置,回填}}voidprint_arr(int arr[],int len){for(int i =0; i < len; i++)
cout << arr[i]<<' ';
cout << endl;}intmain(){int a1[]={7,3,5,8,9,1,2,4,6};int len =sizeof(a1)/sizeof(a1[0]);print_arr(a1, len);ImprovedInsertSort(a1, len);print_arr(a1, len);int a2[]={8,4,6,9,10,2,3,5,7};
len =sizeof(a2)/sizeof(a2[0]);print_arr(a2, len);ImprovedInsertSort(a2, len);print_arr(a2, len);getchar();return0;}
2. 希尔(shell)排序
#include<iostream>#include<string>usingnamespace std;/*--------------- shell 排序 ---------------------
最佳情况时间是 O(N × 1) = O(N),
最坏情况时间是 O(N × N) = O(N²).
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;
随着增量逐渐减少,每组包含的关键词越来越多,当增量减至 1 时,整个文件恰
被分成一组,算法便终止。
稳定性: 希尔排序是非稳定排序算法。
-------------------------------------------------*/voidshellSort1(int array[],int len){int gap = len;// 初始步长do{
gap = gap /3+1;// 步长递减公式--O(n*1.3)for(int i =0; i < gap;++i)// 分组,对每一组,进行插入排序{for(int j = i + gap; j < len; j += gap)// 插入排序{int tmp = array[j];// 临时变量int index = j - gap;while((index >=0)&&(tmp < array[index]))// 从后往前遍历{
array[index + gap]= array[index];// 后移
index -= gap;}
array[index + gap]= tmp;// 回填}}}while(gap >1);}voidprint_arr(int arr[],int len){for(int i =0; i < len; i++)
cout << arr[i]<<' ';
cout << endl;}intmain(){int a1[]={7,3,5,8,9,1,2,4,6};int len =sizeof(a1)/sizeof(a1[0]);print_arr(a1, len);shellSort1(a1, len);print_arr(a1, len);int a2[]={8,4,6,9,10,2,3,5,7};
len =sizeof(a2)/sizeof(a2[0]);print_arr(a2, len);shellSort1(a2, len);print_arr(a2, len);getchar();return0;}
3. 冒泡排序
#include<iostream>#include<string>usingnamespace std;/********************* 冒泡排序 *********************
冒泡排序算法的运作如下:(从后往前)
1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
2. 每次外层循环:对每一对相邻元素作同样的工作
3. 针对所有的元素重复以上的步骤,除了最后一个。
4. 持续每次对越来越少的元素重复上面的步骤,
直到没有任何一对数字需要比较。
O(n²)
稳定性:冒泡排序是一种稳定排序算法
***************************************************///冒泡排序(升序)voidbubbleSort1(int*array,int len)//array[len]{for(int i =0; i < len -1;++i)//进行len-1趟扫描{for(int j =0; j < len -1- i;++j)//第一趟从([0]与[0+1])...比较到([len-2-i]与[len-2-i+1]);然后是第二趟{if(array[j]> array[j +1]){int tmp = array[j];
array[j]= array[j +1];
array[j +1]= tmp;}}}}// 冒泡排序的优化// 添加标志位flag:false-表示没有排好, true-表示已经排好voidbubbleSort2(int*array,int len){int flag =false;for(int i =0;(i < len -1)&&(flag ==false);++i){
flag =true;// 设置标志for(int j =0; j < len -1- i;++j){if(array[j]> array[j +1]){int tmp = array[j];
array[j]= array[j +1];
array[j +1]= tmp;
flag =false;//没有排好}}}}voidprint_arr(int arr[],int len){for(int i =0; i < len; i++)
cout << arr[i]<<' ';
cout << endl;}intmain(){int a1[]={7,3,5,8,9,1,2,4,6};int len =sizeof(a1)/sizeof(a1[0]);print_arr(a1, len);bubbleSort1(a1, len);print_arr(a1, len);int a2[]={8,4,6,9,10,2,3,5,7};
len =sizeof(a2)/sizeof(a2[0]);print_arr(a2, len);bubbleSort1(a2, len);print_arr(a2, len);getchar();return0;}
4. 快速排序
#include<iostream>#include<string>usingnamespace std;/*--------------- 快速排序 ---------------------
数组排序任务可以如下完成:
1)设 k=a[0], 将 k 挪到适当位置,使得比 k 小的元素都
在 k 左边,比 k 大的元素都在 k 右边,和 k 相等的,不关心
在 k 左右出现均可(O(n)时间完成)
2) 把 k 左边的部分快速排序
3) 把 k 右边的部分快速排序
核心:挖坑填数
-------------------------------------------------*/voidswap(int&a,int&b)//交换变量 a,b 值{int tmp = a;
a = b;
b = tmp;}/****
* 参数
* a 数组
* start 数组的第一个有效下标
* end 数组的最后一个有效下标
*/voidQuickSort(int a[],int start,int end){if(start >= end)return;int k = a[start];//每次的基准数:可以随意设置,我习惯使用数组首元素int i = start, j = end;while(i != j){while(i < j && a[j]>= k)//从右往左找比 k 小的--j;swap(a[i], a[j]);while(i < j && a[i]<= k)//从左往右找比 k 大的++i;swap(a[i], a[j]);}//此时k放在了合适的位置(i==j,a[i] == k,并且左边元素都比k小,右边的元素都比k大)QuickSort(a, start, i -1);//把 k 左边的部分快速排序QuickSort(a, i +1, end);//把 k 右边的部分快速排序}voidprint_arr(int arr[],int len){for(int i =0; i < len; i++)
cout << arr[i]<<' ';
cout << endl;}intmain(){int a1[]={7,3,5,8,9,1,2,4,6};int len =sizeof(a1)/sizeof(a1[0]);print_arr(a1, len);QuickSort(a1,0, len -1);print_arr(a1, len);int a2[]={8,4,6,9,10,2,3,5,7};
len =sizeof(a2)/sizeof(a2[0]);print_arr(a2, len);QuickSort(a2,0, len -1);print_arr(a2, len);getchar();return0;}