常用排序算法
bubble_sort:将序列划分为无序区跟有序区,不断通过交换较大的元素至无序区尾完成排序。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <iostream> 3 4 using namespace std; 5 6 void bubble_sort(int arr[], int n){ 7 for (int i = 0; i < n - 1; ++i){ 8 for (int j = 0; j < n - i - 1; ++j){ 9 if (arr[j + 1] < arr[j]){ 10 swap(arr[j + 1], arr[j]); 11 } 12 } 13 } 14 } 15 16 int main(){ 17 int arr[] = { 1, 2, 10, 3, 2, 11, 22}; 18 bubble_sort(arr, sizeof(arr)/ sizeof(int)); 19 for (int i = 0; i < sizeof(arr) / sizeof(int); ++i) 20 cout << arr[i] << " "; 21 cout << endl; 22 return 0; 23 }
heap_sort:利用堆的思想,先建立堆,然后将堆首与堆尾交换,并减少堆的大小,则堆尾后面的即为有序区。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 5 using namespace std; 6 #define lson(x) (x << 1) 7 #define rson(x) (x << 1 | 1) 8 9 void printArray(int a[], int sz){ 10 for (int i = 1; i <= sz; ++i) 11 cout << a[i] << " "; 12 cout << endl; 13 } 14 15 //保持堆的性质 16 void maxHeapify(int a[], int x, int sz){ 17 int Max = x, ls = lson(x), rs = rson(x); 18 if (ls <= sz && a[ls] > a[Max]) Max = ls; 19 if (rs <= sz && a[rs] > a[Max]) Max = rs; 20 if (Max != x){ 21 swap(a[x], a[Max]); 22 maxHeapify(a, Max, sz); 23 } 24 } 25 void buildMaxHeap(int a[], int sz){ 26 for (int i = sz / 2; i >= 1; --i)// 节点i 的父亲即为 i / 2, 故最后一个非叶子节点为 sz / 2 27 maxHeapify(a, i, sz); 28 } 29 void heapSort(int a[], int sz){ 30 buildMaxHeap(a, sz); 31 int len = sz; 32 for (int i = sz; i >= 2; --i){ 33 swap(a[1], a[i]);//最大的放在最后面 34 len--; 35 maxHeapify(a, 1, len); 36 } 37 } 38 int main(){ 39 int arr[] = {0, 4, 2, 1, 3, 6, 5 ,5}; 40 int sz = sizeof(arr) / sizeof(int) - 1; 41 printArray(arr, sz); 42 heapSort(arr, sz); 43 printArray(arr, sz); 44 }
insert_sort:将数组分为有序区和无序区,不断的将无序区的第一个元素插入到有序区。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 5 using namespace std; 6 //插入排序,前 i - 1个为已经排好序的每次把第i个插入到前i - 1当中 7 //选择排序 每次从未排序的里面选择一个最小的。 8 void insert_sort(int list[], int n){ 9 for (int i = 1; i < n; ++i){ 10 if (list[i - 1] > list[i]){ 11 int tmp = list[i], j = i; 12 while (j > 0 && list[j - 1] > tmp){ 13 list[j] = list[j - 1]; 14 --j; 15 } 16 list[j] = tmp; 17 } 18 } 19 } 20 21 int main(){ 22 int x[] = {6, 2, 4, 1, 5, 9}; 23 insert_sort(x, 6); 24 for (int i = 0; i < 6; ++i) 25 cout << x[i] <<" "; 26 cout << endl; 27 return 0; 28 }
merge_sort:将原序列划分为有序的两个序列,然后利用归并算法进行合并。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 5 using namespace std; 6 //可以 利用 非递归, 不回写, 插入排序来优化 7 void merge(int arr[], int low, int mid, int high, int sorted[]){ 8 int i = low, j = mid, k = 0; 9 while (i < mid && j < high){ 10 if (arr[i] < arr[j]){ 11 sorted[k++] = arr[i++]; 12 } 13 else{ 14 sorted[k++] = arr[j++]; 15 } 16 } 17 while (i < mid) sorted[k++] = arr[i++]; 18 while (j < high) sorted[k++] = arr[j++]; 19 for (int i = 0; i < k; ++i) 20 arr[low + i] = sorted[i]; 21 } 22 23 void merge_sort(int arr[], int low, int high, int sorted[]){ 24 if (low + 1 < high){ 25 int mid = (low + high) >> 1; 26 merge_sort(arr,low, mid, sorted); 27 merge_sort(arr,mid, high, sorted); 28 merge(arr, low, mid, high, sorted); 29 } 30 } 31 32 int main(){ 33 int x[] = { 6, 2, 4, 1, 5, 9}; 34 int n = sizeof(x) / sizeof(int); 35 int * sorted = new int[n]; 36 merge_sort(x, 0, n - 1, sorted); 37 for (int i = 0; i < n; ++i) 38 cout << x[i] << " "; 39 cout << endl; 40 }
quick_sort:寻找一个中间点,然后左右递归排序。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 6 using namespace std; 7 8 int partition(int list[], int low, int high){ 9 if (low >= high) return low; 10 11 int k = rand() % (high - low + 1) + low; 12 swap(list[low], list[k]); 13 14 int pivot = list[low]; 15 while (low < high){ 16 while (low < high && list[high] > pivot) high--; 17 list[low] = list[high]; 18 while (low < high && list[low] <= pivot) low++; 19 list[high] = list[low]; 20 } 21 list[low] = pivot; 22 return low; 23 } 24 25 void q_sort(int list[], int low, int high){ 26 int loc = 0; 27 if (low < high){ 28 loc = partition(list, low, high); 29 q_sort(list, low, loc - 1); 30 q_sort(list, loc + 1, high); 31 } 32 } 33 34 //淘宝快排 35 void q_sort2(int list[], int low, int high){ 36 if (low >= high) return ; 37 //随机化 38 int k = rand() % (high - low + 1) + low; 39 swap(list[low], list[k]); 40 41 //插入排序优化 42 if (high - low <= 6){ 43 for (int i = low + 1; i <= high; ++i){ 44 if (list[i - 1] > list[i]){ 45 int tmp = list[i], j = i; 46 while (j > 0 && list[j - 1] > tmp){ 47 list[j] = list[j - 1]; 48 j--; 49 } 50 list[j] = tmp; 51 } 52 } 53 return ; 54 } 55 //qsort 56 int x = list[low], j = low; 57 for (int i = low + 1; i <= high; ++i) 58 if (list[i] < x) swap(list[++j], list[i]); 59 swap(list[low], list[j]); 60 q_sort2(list, low, j - 1); 61 q_sort2(list, j + 1, high); 62 } 63 64 int main(){ 65 srand(time(NULL)); 66 int x[10] = {6, 2, 4, 1, 5, 9, 10, 2, 11, 12}; 67 q_sort2(x, 0, 9); 68 for (int i = 0; i <= 9; ++i) 69 cout << x[i] << " "; 70 cout << endl; 71 return 0; 72 }
shell_sort:增量缩小排序,分组插入。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 5 using namespace std; 6 //希尔排序就是分组插入排序 7 //便于理解 8 void shell_sort1(int a[], int n){ 9 for (int gap = n / 2; gap > 0; gap /= 2){//步长 10 for (int i = 0; i < gap; ++i){ // 直接插入排序 11 for (int j = i + gap; j < n; j += gap){ 12 if (a[j] < a[j - gap]){ 13 int tmp = a[j], k = j - gap; 14 while (k >= 0 && a[k] > tmp){ 15 a[k + gap] = a[k]; 16 k -= gap; 17 } 18 a[k + gap] = tmp; 19 } 20 } 21 } 22 } 23 } 24 25 //简化代码 26 void shell_sort2(int a[], int n){ 27 for (int gap = n / 2; gap > 0; gap /= 2){ 28 for (int j = gap; j < n; ++j){ 29 if (a[j] < a[j - gap]){ 30 int tmp = a[j], k = j - gap; 31 while (k >= 0 && a[k] > tmp){ 32 a[k + gap] = a[k]; 33 k -= gap; 34 } 35 a[k + gap] = tmp; 36 } 37 } 38 } 39 } 40 41 int main(){ 42 int x[] = {2, 4, 6, 3,5 ,1}; 43 int n = sizeof(x) / sizeof(int); 44 shell_sort1(x, 6); 45 for (int i = 0; i < 6; ++i) 46 cout <<x[i] << " "; 47 cout << endl; 48 int y[] = {8, 4, 6, 3,5 ,1}; 49 n = sizeof(y) / sizeof(int); 50 shell_sort1(y, 6); 51 for (int i = 0; i < 6; ++i) 52 cout <<y[i] << " "; 53 cout << endl; 54 return 0; 55 }