2018 3 17
今日总结一下C++中的排序算法:
1冒泡排序
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
这个算法的名字由来是因为越大的元素会经由交换慢慢“浮”到数列的顶端。(来源百度百科)
C++实现:
1 #include "stdafx.h" 2 #include <iostream> 3 using namespace std; 4 int ha[] = {1,7,4,2,6,5,8,3}; 5 6 template <typename T> 7 void Bubble_Sort(T *pDst,const int nLen) 8 { 9 int cycle; 10 //外层循环,控制遍历的次数(N-1(N为待排序的数组大小)) 11 for (cycle=0; cycle<(nLen-1) ; cycle++) 12 { 13 //内层循环,每次遍历到前一次最大值之前为止 14 for (int i=0; i < (nLen - 1-cycle); i++) 15 { 16 if (pDst[i] > pDst[i + 1]) 17 { 18 T tTemp = pDst[i]; 19 pDst[i] = pDst[i + 1]; 20 pDst[i + 1] = tTemp; 21 } 22 } 23 } 24 } 25 26 int main() 27 { 28 //冒泡 29 30 Bubble_Sort<int>(ha,8); 31 for (int i = 0; i < 8; i++) 32 { 33 printf("%d-",ha[i]); 34 getchar(); 35 } 36 return 0; 37 }
2 选择排序
工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法(比如序列[5, 5, 3]第一次就将第一个[5]与[3]交换,导致第一个5挪动到第二个5后面)。
C++实现:
1 //升序 2 template <typename T> 3 void Select_Sort(T *pDst, const int nLen) 4 { 5 T tTemp; 6 7 //遍历nLen次,每次找到最小的值,交换 8 for (int i = 0; i < nLen; i++) 9 { 10 for (int j = i; j < nLen; j++) 11 { 12 if (pDst[j] <pDst[i]) 13 { 14 tTemp=pDst[i]; 15 pDst[i] = pDst[j]; 16 pDst[j] = tTemp; 17 18 } 19 else 20 continue; 21 } 22 } 23 24 } 25 int main() 26 { 27 //冒泡 28 29 //Bubble_Sort<int>(ha,8); 30 Select_Sort<int>(ha,8); 31 for (int i = 0; i < 8; i++) 32 { 33 printf("%d-",ha[i]); 34 } 35 return 0; 36 }
3 归并排序
将两个有序(同一种序)的数组合并为一个有序数组
(1)二路归并。二路归并的最好情况时间复杂度为:O(Min{sizof(a),sizeof(b)})
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // ConsoleApplication4.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include "atlstr.h" 6 #include <iostream> 7 #include <vector> 8 using namespace std; 9 ////// 10 //二路归并排序。将两个表,合并成一个表的过程称为二路归并 11 //如:对两个y有序的数组 进行二路归并 12 const int a[] = {1,2,3}; 13 const int b[] = {1,2,3,4,5,6,7}; 14 15 int* Merger_Sort(const int *a,const int *b,int nLen1,int nLen2) 16 { 17 int *pDst = new int[nLen1+nLen2]; 18 int k = 0; 19 int i = 0; 20 int j = 0; 21 while (i < nLen1&&j < nLen2) 22 { 23 if (a[i] <= b[j]) 24 { 25 pDst[k] = a[i]; 26 i++; 27 } 28 else 29 { 30 pDst[k] = b[j]; 31 j++; 32 } 33 k++; 34 } 35 while (i < nLen1) 36 { 37 pDst[k] = a[i]; 38 i++; 39 k++; 40 } 41 while (j < nLen2) 42 { 43 pDst[k] = b[j]; 44 j++; 45 k++; 46 } 47 return pDst; 48 } 49 50 int main() 51 { 52 int *p = NULL; 53 p = Merger_Sort(a,b,3,7); 54 for (int i = 0; i <10; i++) 55 { 56 cout << p[i]; 57 } 58 delete[] p; 59 60 getchar(); 61 return 0; 62 }
(2) 普通归并排序 ;将二路归并扩展到一般情况,将一个序列分为N组,每组都是一个有序的数组,对两两之间进行归并
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 // ConsoleApplication7.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 //二路归并的前提是两个结构的元素已经是有序的(同样的顺序) 6 int a[] = { 1,3,4,5,6 }; 7 int b[] = { 2,3,8,9,10,18 }; 8 void Two_MergeSort(int *pA1, int *pA2, int nA1Len, int nA2Len, int *pOut) 9 { 10 int i = 0; int j = 0; 11 int nDstPos = 0; 12 while (i < nA1Len&&j < nA2Len) 13 { 14 if (pA1[i] > pA2[j]) 15 { 16 //找到同一顺序的元素中较小的放入pOut中 17 pOut[nDstPos++] = pA2[j++]; 18 } 19 else 20 pOut[nDstPos++] = pA1[i++]; 21 } 22 while (i < nA1Len) 23 { 24 pOut[nDstPos++] = pA1[i++]; 25 } 26 while (j<nA2Len) 27 { 28 pOut[nDstPos++] = pA2[j++]; 29 } 30 } 31 32 //输入的Pos指的是坐标,可以比较一下与二路归并的区别 33 void General_Two_MergeSort(int *pA, int nStartPos, int nMidPos, int nEndPos, int *pOut) 34 { 35 int i = nStartPos; 36 int j = nMidPos + 1; 37 int k = nEndPos; 38 int nDstPos = nStartPos; 39 printf("对区间[%d,%d]和区间[%d,%d]进行排序 ", nStartPos, nMidPos, nMidPos + 1, nEndPos); 40 while (i <= nMidPos&&j <= nEndPos) 41 { 42 if (pA[i] > pA[j]) 43 { 44 pOut[nDstPos++] = pA[j++]; 45 } 46 else 47 { 48 pOut[nDstPos++] = pA[i++]; 49 } 50 } 51 while (i <= nMidPos) 52 { 53 pOut[nDstPos++] = pA[i++]; 54 } 55 while (j <= nEndPos) 56 { 57 pOut[nDstPos++] = pA[j++]; 58 } 59 for (int n = nStartPos; n <= nEndPos; n++) 60 { 61 pA[n] = pOut[n]; 62 } 63 static int nCount = 0; 64 printf("第%d次调用 ",++nCount); 65 //printf("参数分别是:StartPos:%d,MidPos:%d,EndPos:%d ", nStartPos,nMidPos,nEndPos); 66 //printf("当前排序的成员有%d个,分别是: ",nEndPos-nStartPos+1); 67 for (int n = nStartPos; n <= nEndPos; n++) 68 { 69 printf("%d ",pOut[n]); 70 } 71 printf(" "); 72 printf(" "); 73 printf(" "); 74 } 75 76 77 //推广到更普通的归并排序 78 //归并排序的核心是将一串数字中的数字分成两组,先对分成的每一组进行深度归并,最后再对初始的两组进行归并 79 void Merge_Sort(int *pA, int nLow, int nHigh, int *pOut) 80 { 81 if (nLow < nHigh) 82 { 83 int nMid = (nLow + nHigh) / 2; 84 //左边递归,直到只含有一个元素 85 Merge_Sort(pA, nLow, nMid, pOut); 86 //右边递归,直到只含有一个元素 87 Merge_Sort(pA, nMid + 1, nHigh, pOut); 88 //对两个元素进行递归排序 89 General_Two_MergeSort(pA, nLow, nMid, nHigh, pOut); 90 } 91 92 93 } 94 95 96 int main() 97 { 98 int c[7] = { 0 }; 99 int Dst[] = { 1,3,5,7,9,11,13 }; 100 //Two_MergeSort(a,b,5,6,c); 101 Merge_Sort(Dst, 0, 6, c); 102 int i = 0; 103 while (i < 7) 104 { 105 printf("%d ", c[i++]); 106 } 107 108 109 getchar(); 110 return 0; 111 }