常用排序算法总结

常用排序算法总结:选择法、冒泡法、直接插入法、希尔算法、快速算法、归并算法

2019年04月08日 10:52:26 意义丶 阅读数:1622

本文总结了六种排序算法,分别是:选择法、冒泡法、直接插入法、希尔算法、快速算法、归并算法。

一、选择法排序:
/*

选择排序的基本思想是:每一趟在n-i+1(i=1,2,…n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录。基于此思想的算法主要有简单选择排序、树型选择排序和堆排序。
*/

/*
第1趟,在待排序记录r[1]~r[n]中选出最小的记录,将它与r[1]交换;
第2趟,在待排序记录r[2]~r[n]中选出最小的记录,将它与r[2]交换;
以此类推,第i趟在待排序记录r[i]~r[n]中选出最小的记录,将它与r[i]交换,
使有序序列不断增长直到全部排序完毕。所以只会循环n-1次。
*/

 
  1. template<class T>

  2. void SelectSort(T *array, const int len)

  3. {

  4. //T temp = 0;

  5. for (int i = 0; i < len - 1; i++)

  6. {

  7. int index_min = i;//假设待排序列中的第一个当做最小的,然后在待排序列中找到最小的

  8. for (int j = i + 1; j < len; j++) //从第i个元素的后面一个元素开始找剩余的序列中最小的值的下标。

  9. {

  10. if (array[j] < array[index_min])

  11. {

  12. index_min = j;//找到新的最小的元素了

  13. }

  14. }

  15. if (index_min != i)//若无序区第一个元素不是无序区中最小元素,则进行交换

  16. {

  17. array[index_min] = array[index_min] ^ array[i];

  18. array[i] = array[index_min] ^ array[i];

  19. array[index_min] = array[index_min] ^ array[i];

  20.  
  21. /*两种数据交换方式,第二种需要在前面定义一个缓存temp

  22. //temp = array[index];

  23. //array[index] = array[i];

  24. //array[i] = temp;

  25. */

  26. }

  27. }

  28. }

二、冒泡法排序:
/*

冒泡法排序与选择法类似,选择法是先找到最小值的下标,而冒泡法是找到一个小的(不一定是最小的)就交换。
*/

 
  1. template<class T>

  2. void BubbleSort(T *array, const int len)

  3. {

  4. for(int i = 0; i < len - 1; i++)

  5. {

  6. for(int j = i + 1; j < len; j++)

  7. {

  8. if(array[i] > array[j])

  9. {

  10. array[i] = array[i] ^ array[j];

  11. array[j] = array[i] ^ array[j];

  12. array[i] = array[i] ^ array[j];

  13. }

  14. }

  15. }

  16. }

三、直接插入法排序:
/*

在排序之前我们需要搞清一个思路,新插入一个数据的时候,排序过后的数组都是从小到大排列好的,所以我们需要从后往前查找,直到找到比我们要插入的数字还小的值。这个时候我们需要一个变量j作为标识
*/

 
  1. template<class T>

  2. void InsertSort(T * array, const int len)

  3. {

  4. T temp = 0;

  5. for (int i = 1; i < len; i++)//还是n-1趟,只是这里从1开始,即第二个元素开始,前面的是有序的。

  6. {

  7. temp = array[i];//取出这个要和前面有序序列比较的元素。

  8. int j = 0;

  9. for (j = i - 1;j >= 0;j--)//这个元素的和前面有序序列比较,直到下标0

  10. {

  11. if (array[j] > temp)//将大于temp的数向后移动

  12. {

  13. array[j + 1] = array[j];

  14. }

  15. else

  16. {

  17. break;//不再比temp大了,就不移动了

  18. }

  19. }

  20. //移动完,就插入元素

  21. array[j + 1] = temp;//这里,因为j--,跳出循环时,j多减了一次

  22. }

  23. }

四、希尔排序算法:
/*

在直接插入排序算法中,每次插入一个数,使有序序列只增加1个节点,并且对插入下一个数没有提供任何帮助。如果比较相隔较远距离(称为增量)的数,使得数移动时能跨过多个元素,则进行一次比较就可能消除多个元素交换。算法先将要排序的一组数按某个增量d分成若干组,每组中记录的下标相差d.对每组中全部元素进行排序,然后再用一个较小的增量对它进行,在每组中
再进行排序。当增量减到1时,整个要排序的数被分成一组,排序完成。
*/

 
  1. template<class T>

  2. void ShellSort(T *array, int len)

  3. {

  4. T temp;

  5. int gap = len;////初始化划分增量

  6. do

  7. {

  8. //业界统一实验的 平均最好情况 经过若干次后,收敛为1(跳出循环)

  9. gap = gap / 3 + 1;

  10. for (int i = gap; i < len; i += gap) //对每个划分进行 直接插入法排序

  11. {

  12. temp = array[i];//找到当前这个元素

  13. int j = 0;

  14. for (j = i - gap; j >= 0; j -= gap)//这个元素的和前面有序序列比较,直到下标0

  15. {

  16. if (array[j] > temp)//将大于temp的数向后移动

  17. {

  18. array[j + gap] = array[j];

  19. }

  20. else

  21. {

  22. break;//不再比temp大了,就不移动了

  23. }

  24. }

  25. //移动完,就插入元素

  26. array[j + gap] = temp;//这里,因为j-gap,跳出循环时,j多减了一次gap

  27. }

  28. } while (gap > 1);

  29. }

五、希尔排序算法:
/*

它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
*/

 
  1. template<class T>

  2. void Quicksort(T *array, int low, int high)//high = len-1

  3. {

  4. if (low >= high)

  5. {

  6. return;//递归结束标志

  7. }

  8. int first = low;

  9. int last = high;

  10. int key = array[first];//用字表的第一个记录作为枢轴(区分小的分段和大的分段)

  11. while (first < last)

  12. {

  13. while (first < last && array[last] >= key)

  14. {

  15. --last;

  16. }

  17. array[first] = array[last];/*将比key小的移到低端*/

  18. while (first<last && array[first] <= key)

  19. {

  20. ++first;

  21. }

  22. array[last] = array[first];/*将比key大的移到高端*/

  23. }

  24. array[first] = key;//重新确定枢轴的值,这里的first = last;(一定相等)//前面的枢轴值被覆盖了。

  25. Quicksort(array, low, first - 1);//对左边的数据段排序

  26. Quicksort(array, first + 1, high);//对右边的数据段排序

  27. }

六、归并排序算法:
/*

归并排序法(Merge Sort,以下简称MS)是分治法思想运用的一个典范。其主要算法操作可以分为以下步骤:
Step 1:将n个元素分成两个含n/2元素的子序列
Step 2:用MS将两个子序列递归排序(最后可以将整个原序列分解成n个子序列)
Step 3:合并两个已排序好的序列(合并是该算法的核心)
*/

 
  1. template<class T>

  2. void Merge(T src[], T des[], int low, int mid, int high);

  3. template<class T>

  4. void MSort(T src[], T des[], int low, int high, int max);

  5.  
  6. template<class T>

  7. void MergeSort(T *array, int len)// O(n*logn)

  8. {

  9. MSort(array, array, 0, len - 1, len);

  10. }

  11.  
  12. //每次分为两路 当只剩下一个元素时,就不需要在划分

  13. template<class T>

  14. void MSort(T src[], T des[], int low, int high, int max)

  15. {

  16. if (low == high) //只有一个元素,不需要归并,结果赋给des[low]

  17. {

  18. des[low] = src[low];

  19. }

  20. else //如果多个元素,进行两路划分

  21. {

  22. int mid = (low + high) / 2;

  23. T* space = new T[max];

  24.  
  25. //递归进行两路,两路的划分

  26. //当剩下一个元素的时,递归划分结束,然后开始merge归并操作

  27. if (space != nullptr)

  28. {

  29. MSort(src, space, low, mid, max);

  30. MSort(src, space, mid + 1, high, max);

  31. Merge(space, des, low, mid, high); //调用归并函数进行归并

  32. }

  33. delete[]space;

  34. }

  35. }

  36.  
  37. template<class T>

  38. void Merge(T src[], T des[], int low, int mid, int high)

  39. {

  40. int i = low;

  41. int j = mid + 1;

  42. int k = low;

  43.  
  44. while ((i <= mid) && (j <= high)) //将小的放到目的地中

  45. {

  46. if (src[i] < src[j])

  47. {

  48. des[k++] = src[i++];

  49. }

  50. else

  51. {

  52. des[k++] = src[j++];

  53. }

  54. }

  55.  
  56. while (i <= mid) //若还剩几个尾部元素

  57. {

  58. des[k++] = src[i++];

  59. }

  60.  
  61. while (j <= high) //若还剩几个尾部元素

  62. {

  63. des[k++] = src[j++];

  64. }

  65. }

七、主函数调用:

 
  1. #include <iostream>

  2. #include <string>

  3. using namespace std;

  4.  
  5. template<class T>

  6. void prinft_array(T &array)

  7. {

  8. for (int i = 0; i < sizeof(array)/sizeof(array[0]); i++)

  9. {

  10. cout << "array[" << i << "]:" << array[i] << endl;

  11. }

  12. }

  13.  
  14. int main(void)

  15. {

  16. int array1[] = { 10, 50, 60, 20, 12, 52, 62, 22, 14, 54, 64, 24 };

  17. //char array2[] = { 'a', 'd', 'b', 'c'};

  18. int len = sizeof(array1) / sizeof(array1[0]);

  19. int low = 0;//指向开头

  20. int high = len - 1;//指向末尾

  21. cout << "排序之前" << endl;

  22. prinft_array(array1);

  23. //排序:

  24. SelectSort(array1,len);

  25. BubbleSort(array1, len);

  26. InsertSort(array2, len);

  27. ShellSort(array2, len);

  28. Quicksort(array1, low, high);

  29. MergeSort(array1, len);

  30. cout << "排序之后" << endl;

  31. prinft_array(array1);

  32.  
  33. system("pause");

  34. return 0;

  35. //自动排版:ctrl+K,ctrl+F

  36. }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值