多种排序算法的实现与比较
排序算法的分类有多种分法. 是否是基于比较的; 是否是稳定排序; 当然也可按照时间复杂度和空间复杂度来进行划分. 而本文关注的重点在于时间复杂度及基于比较的排序. 基排序和计数排序等在此就不进行讨论了.
头文件 sort.h
1 #include <iostream> 2 3 class sort 4 { 5 public: 6 static bool bubble_sort(int* arry, int n);//冒泡排序 7 static bool insert_sort_no(int* arry, int n);//插入排序,非递归 8 static bool insert_sort_re(int* arry, int n);//插入排序,递归 9 static bool select_sort(int* arry, int n);//选择排序 10 static bool merge_sort(int* arry, int n);//归并排序 11 static bool heap_sort(int* arry, int n);//堆排序 12 static bool quick_sort(int* arry, int n);//快速排序 13 };
排序算法实现代码
sort.cpp
1 #include "sort.h" 2 3 4 //功能: 插入排序,非递归 5 //输入: 数组 6 //输出: 已排序数组 7 //版本: 1.0 8 //最后修改时间: 2012-7-5 9 //修订人: 陈飞 10 bool sort::insert_sort_no(int* num, int n) 11 { 12 if (n<1) 13 { 14 return false; 15 } 16 17 //插入排序 18 int temp; 19 for (int i=1; i<n; i++) 20 { 21 temp = num[i]; 22 int j; 23 for(j=i-1; j>=0 && num[j]>temp; j--) 24 { 25 num[j+1]=num[j]; 26 } 27 num[j+1] = temp; 28 29 } 30 return true; 31 } 32 33 //插入排序,递归 34 //2012-7-14 35 //大于一定数时栈溢出 36 bool sort::insert_sort_re(int *arry, int n) 37 { 38 if (0==n) 39 { 40 return true; 41 } 42 else 43 { 44 insert_sort_re(arry, n-1); 45 // 46 int temp = arry[n-1]; 47 int i; 48 for (i=n-2; i>=0 && arry[i]>temp; i--) 49 { 50 arry[i+1]=arry[i]; 51 } 52 arry[i+1]=temp; 53 } 54 return true; 55 } 56 57 58 //功能: 归并排序,递归 59 //输入: 乱序数组 60 //输出: 已排序数组 61 //版本: 1.0 62 //最后修改时间: 2012-7-9 63 //修订人: 陈飞 64 65 //归并辅助函数 66 void merge_assist(int *arry1, int n1, int *arry2, int n2, int* whole) 67 { 68 //int* whole = (int *)malloc((n2+n1)*sizeof(int)); 69 int i1, i2; 70 for (i1=0, i2=0; i1<n1 && i2<n2;) 71 {//从两个数组中取小的到whole数组中 72 if (arry1[i1]<arry2[i2]) 73 { 74 whole[i1+i2] = arry1[i1++]; 75 } 76 else 77 { 78 whole[i1+i2] = arry2[i2++]; 79 } 80 } 81 //剩余排序的加到whole末尾 82 if (i1==n1) 83 { 84 for (;i2<n2;i2++) 85 { 86 whole[i1+i2] = arry2[i2]; 87 } 88 } 89 else 90 { 91 for (;i1<n1; i1++) 92 { 93 whole[i1+i2] = arry1[i1]; 94 } 95 } 96 97 //复制回原数组 98 for(int i=0; i<n1+n2; i++) 99 { 100 arry1[i] = whole[i]; 101 } 102 //free(whole); 103 } 104 105 void merge_main(int *arry, int n, int* assist) 106 { 107 if (n>1) 108 { 109 merge_main(arry, n/2, assist); 110 merge_main(arry+n/2, n-n/2, assist); 111 merge_assist(arry, n/2, arry+n/2, n-n/2, assist); 112 } 113 } 114 115 bool sort::merge_sort(int *arry, int n) 116 { 117 //辅助数组的生成 118 int* assist = (int*)malloc(sizeof(int)*n); 119 merge_main(arry, n, assist); 120 free(assist); 121 return true; 122 } 123 124 125 //冒泡排序 2012-7-31 v1.0 126 bool sort::bubble_sort(int *arry, int n) 127 { 128 int i, j, t; 129 for (i=0; i<n; i++) 130 { 131 for (j=0; j<n-i-1; j++) 132 { 133 if (arry[j]>arry[j+1]) 134 { 135 t=arry[j]; 136 arry[j]=arry[j+1]; 137 arry[j+1]=t; 138 } 139 } 140 } 141 return true; 142 } 143 //选择排序 2012-7-31 v1.0 144 bool sort::select_sort(int *arry, int n) 145 { 146 int i, j, t; 147 for (i=0;i<n;i++) 148 { 149 for (j=i+1;j<n;j++) 150 { 151 if (arry[j]<arry[i]) 152 { 153 t=arry[j]; 154 arry[j]=arry[i]; 155 arry[i]=t; 156 } 157 } 158 } 159 return true; 160 } 161 162 163 164 //快排 2012-7-31 v1.0 165 bool sort::quick_sort(int *a, int n) 166 { 167 if(n<=1) return true; 168 else 169 { 170 //随机化快排 171 //swap(a[0], a[random(0,n-1)]); 172 int i=0, j=1,t; 173 for (;j<n;) 174 { 175 if (a[j]<a[0]) 176 { 177 t=a[i+1]; a[i+1]=a[j];a[j]=t; 178 i++; j++; 179 } 180 else 181 { 182 j++; 183 } 184 } 185 t=a[i]; a[i]=a[0];a[0]=t; 186 quick_sort(a, i); 187 quick_sort(a+i+1, n-i-1); 188 return true; 189 } 190 } 191 192 //堆排序 193 //2012-7-31 v1.0 194 void max_heapify(int* a, int n, int i) 195 {//最大堆的保持 196 int l = 2*i; 197 int r = 2*i + 1; 198 int max_value = i; 199 if (l<=n && a[l-1]>a[i-1]) 200 { 201 max_value = l; 202 } 203 if (r<=n && a[r-1]>a[max_value-1]) 204 { 205 max_value = r; 206 } 207 if (max_value != i) 208 { 209 int t=a[max_value-1]; 210 a[max_value-1]=a[i-1]; 211 a[i-1]=t; 212 max_heapify(a, n, max_value); 213 } 214 } 215 216 void build_max_heap(int* a, int n) 217 { 218 int i; 219 for (i=n/2; i>0; i--) 220 { 221 max_heapify(a, n, i); 222 } 223 } 224 225 bool sort::heap_sort(int *a, int n) 226 { 227 build_max_heap(a,n); 228 for (int i=n; n>1; n--) 229 { 230 int t = a[0]; a[0]=a[n-1]; a[n-1]=t; 231 max_heapify(a, n-1, 1); 232 } 233 return true; 234 }
冒泡排序
最早学习的算法, 通过相邻两个数比较与交换. 最终达到排序的目的. 名为冒泡的原由在于比较过程当中犹如一个气泡不断上冒. 我在实现的时间却一直用着它的下沉. 时间复杂度为O(n), 空间复杂度为O(1).
选择排序
不断选择最值放于其中一侧. 如:第一个数与后续逐个比较, 若小于(或大于)第一个数则交换. 一遍后第二个数如是行.时间复杂度为O(n*n), 空间复杂度为O(1).
插入排序
假设先前的数已排好序, 通过不断将后一个数插入到先前有序数组中最终实现排序. 时间复杂度为O(n*n), 空间复杂度为O(1).
归并排序
要排序一个数组,先排序其均分的两个子数组. 递归. 合并两个已排序的数组. 时间复杂度为O(nlog(n)), 空间复杂度为O(n).
快速排序
随机选择一个数为轴, 大于该数的放于一端, 小于该数的放于另一端. 对两端的数组继续如是行. 直到数小于等于1为止. 平均时间复杂度为(nlog(n)), 空间复杂度为O(1).
堆排序
构造堆, 通过不断取最值,重构进行排序. 时间复杂度为O(nlog(n)), 空间复杂度为O(1).
以下为其性能比较.
单位毫秒. 计时方式误差较大.
冒泡 | 选择 | 插入 | 归并 | 快排 | 堆排 | |
2W | 1478 | 1450 | 358 | |||
20W | 26450 | 78 | 47 | 200 | ||
200W | 800 | 810 | 2330 |