当前位置:   article > 正文

常见的排序算法C/C++_擂台法排序c语言

擂台法排序c语言

目录

一、冒泡排序

二、选择排序(擂台法)

三、插入排序

四、希尔排序(缩小增量排序)

五、快速排序

六、堆排序

七、归并排序(合并排序)

八、递归排序


一、冒泡排序

【思路】冒泡排序算法通过多次比较和交换来实现排序,其排序流程如下

1)对数组中的各数据,依次比较相邻的两个元素的大小;

2)如果前面的数据大于后面的数据,就交换这两个数据。经过第一轮的多次比较排序后,便可把最大的数据排好;

3)再用相同的方法把剩下的数据逐个进行比较,最后便可按照从小到大的顺序排好。

  1. void BubbleSort(int *a, int len) {
  2. for (int i = 0; i < len - 1; i++) //进行 len-1 次比较
  3. for (int j = 0; j < len - i - 1; j++) //在每次中进行 len-i-1 次比较
  4. if (a[j] > a[j + 1]) //按升序排序,降序用<
  5. {
  6. int temp = a[j + 1]; //交换相邻的两个元素
  7. a[j + 1] = a[j];
  8. a[j] = temp;
  9. }
  10. }

 

 

二、选择排序(擂台法)

【思路】选择排序法在每一步中选取最小值来重新排序。

排序基本流程:

1)首先从原始数组中选择一个最小的数据,将其和位置位于第1个的数据交换;

2)从剩下的n-1个数据中选择次小的一个元素,将其和位于第2个的数据交换;

3)这样不断重复,知道最后两个数据完成交换。

  1. void SelectionSort(int *a, int len) {//升序
  2. int i, j, k;
  3. for (i = 0; i < len - 1; i++) {//进行 len-1 次比较
  4. k = i;
  5. for (j = i + 1; j < len; j++)
  6. if (a[j] < a[k]) k = j;//存储下标,不直接交换
  7. if (k != i) {
  8. int temp = a[i];
  9. a[i] = a[k];
  10. a[k] = temp;
  11. }
  12. }
  13. }
  14. void SelectionSort1(int *a, int len) {//降序,按住一个位置不动,循环出一个最大值,好比打擂台
  15. int i, j, max=0;
  16. for (i = 0; i < len - 1; i++) {
  17. max = i;
  18. for (j = i + 1; j < len; j++) {
  19. if (a[max] < a[j]) {
  20. int temp = a[j];
  21. a[j] = a[max];
  22. a[max] = temp;
  23. }
  24. }
  25. }
  26. }

以上两个都是选择排序,SelectionSort更高效。

 

 

三、插入排序

【思路】插入排序算法通过比较和插入来实现排序,其排序流程如下:

1)首先对数组的前两个数据进行从小到大排序;

2)将第3个数据与排好序的两个数据比较,将第3个数据插入合适的位置;

3)将第4个数据插入已排好的前3个数据中;

4)不断重复上述过程,直到把最后一个数据插入合适的位置。

  1. void InsertionSort(int *a, int len) {
  2. int i, j, t;
  3. for (i = 1; i < len; i++) {
  4. t = a[i];
  5. j = i - 1;
  6. while (j >= 0 && t < a[j]) {
  7. a[j + 1] = a[j];
  8. j--;
  9. }
  10. a[j + 1] = t;
  11. }
  12. }

 

 

四、希尔排序(缩小增量排序)

【思路】希尔排序算法严格来说是基于插入排序的思想,Shell排序算法的排序流程如下:

  1. 将有n个元素的素组分为n/2个序列,第1个数据和第n/2+1个数据为1对,等等,依次类推;
  2. 一次循环使每一个序列对排好顺序;
  3. 变为n/4个序列,再次排序;
  4. 不断重复上述过程,随着序列减少直至最后变为1个,完成整个排序。
  1. void ShellSort(int *a, int len) {
  2. int i, j, r, temp;
  3. for (r = len / 2; r >= 1; r /= 2) {//划组排序
  4. //每一趟采用插入排序
  5. for (i = r; i < len; i++) {
  6. temp = a[i];
  7. j = i - r;
  8. while (j >= 0 && temp < a[j]) {
  9. a[j + r] = a[j];
  10. j -= r;
  11. }
  12. a[j + r] = temp;
  13. }
  14. }
  15. }

 

 

五、快速排序

【思路】快速排序算法通过多次比较和交换来实现排序,其排序流程如下:

  1. 首先设置一个分界值,通过分界值将数组分成左右两部分;
  2. 将大于或等于分界值的数据集中到数组右边,小于边界值的数据集中到数组的左边;
  3. 左边和右边的数据可以独立排序。对于左侧的数据,又可以取一个分界值,将该数据分成左右两部分,同样在左边放置较小值,右边放置较大值。右侧的数据也可以做类似处理;
  4. 重复以上过程,可以看出这是一个递归定义。通过递归将左侧部分排好序后,再递归排好右侧部分的顺序。
  1. void Quick_Sort(int *a, int begin, int end) {
  2. if (begin > end)
  3. return;
  4. int tmp = a[begin];
  5. int i = begin;
  6. int j = end;
  7. while (i != j) {
  8. while (a[j] >= tmp && j > i)
  9. j--;//从右往左找比tmp小的
  10. while (a[i] <= tmp && j > i)
  11. i++;//从左往右找比tmp大的
  12. if (j > i) {
  13. int t = a[i];
  14. a[i] = a[j];
  15. a[j] = t;
  16. }
  17. }
  18. a[begin] = a[i];
  19. a[i] = tmp;
  20. Quick_Sort(a, begin, i - 1);
  21. Quick_Sort(a, i + 1, end);
  22. }

六、堆排序

堆(heap):完全二叉树,父结点的值大于子结点的值。

  1. void print(int a[], int n) {//打印数组
  2. for (int i = 0; i < n; i++)
  3. cout << a[i] << " ";
  4. cout << endl;
  5. }
  6. void HeapSort(int a[], int n) {
  7. int i, j, k;
  8. int t;
  9. for (i = n / 2 - 1; i >= 0; i--) {//建成大顶堆
  10. while (2*i+1<n)//第2个结点有右子树
  11. {
  12. j = 2 * i + 1;
  13. if (j + 1 < n) {
  14. if (a[j] < a[j + 1])//左子树小于右子树,则需要比较右子树
  15. j++;//序号加1,指向右子树
  16. }
  17. if (a[i]<a[j]){//比较i与j为序号的数据
  18. t = a[i];
  19. a[i] = a[j];
  20. a[j] = t; //交换数据
  21. i = j;//堆被破坏,需要重新调整
  22. }
  23. else {//比较左右子节点均大,则堆未破坏,不再需要调整
  24. break;
  25. }
  26. }
  27. }
  28. //输出构成的堆
  29. cout << "原数据构成的堆:";
  30. print(a, n);
  31. for (i = n - 1; i > 0; i--) {
  32. t = a[0];
  33. a[0] = a[i];
  34. a[i] = t;
  35. k = 0;
  36. while (2 * k + 1 < i) {
  37. j = 2 * k + 1;
  38. if (j + 1 < i) {
  39. if (a[j] < a[j + 1])
  40. j++;
  41. }
  42. if (a[k] < a[j]) {
  43. t = a[k];
  44. a[k] = a[j];
  45. a[j] = t;
  46. k = j;
  47. }
  48. else {
  49. break;
  50. }
  51. }
  52. cout << "第" << n - i << "步排序:";
  53. print(a, 10);
  54. }
  55. }

  

 第1步排序 对应上面第5个树,

 第2步排序 对应上面第8个树,

 第2步排序 对应上面最后个树

 

 

七、归并排序(合并排序)

归并排序:采用分治的思想,将数组(Array)划分为两个子数组(left和right),然后递归(MergeSort)的将每个子数组再进行划分,直到数组中只剩一下一个元素,然后开始排序合并(Merge),直到将所有的子数组合并完成,整个数据就是有序的了。

  1. void print(int a[], int n) {
  2. for (int i = 0; i < n; i++)
  3. cout << a[i] << " ";
  4. cout << endl;
  5. }
  6. void MergeOne(int a[], int b[], int n, int len) {//完成一遍合并的函数
  7. int i, j, k, s, e;
  8. s = 0;
  9. while (s + len < n) {
  10. e = s + 2 * len - 1;
  11. if (e >= n) {//最后一段可能少于len个结点
  12. e = n - 1;
  13. }
  14. //相邻有序段合并
  15. k = s;
  16. i = s;
  17. j = s + len;
  18. while (i < s + len && j <= e) {//如果两个有序表都未结束时,循环比较
  19. if (a[i] <= a[j])//将较小的数组放到数组b中
  20. b[k++] = a[i++];
  21. else
  22. b[k++] = a[j++];
  23. }
  24. while (i < s + len) {//未合并的部分复制到数组b中
  25. b[k++] = a[i++];
  26. }
  27. while (j <= e) {//未合并的部分复制到数组b中
  28. b[k++] = a[j++];
  29. }
  30. s = e + 1;//下一对有序段中左段的开始下标
  31. }
  32. if (s < n) {//将剩余的一个有序段从数组a中复制到数组b
  33. for (; s < n; s++) {
  34. b[s] = a[s];
  35. }
  36. }
  37. }
  38. void MergeSort(int a[], int n) {//合并排序
  39. int *p;
  40. int h, count, len, f;
  41. count = 0;//排序步骤
  42. len = 1;//有序序列的长度
  43. f = 0;//标志
  44. if (!(p = (int *)malloc(sizeof(int)*n))) {//分配内存空间
  45. cout << "分配内存失败!";
  46. exit(0);
  47. }
  48. while (len < n) {
  49. if (f == 1) {
  50. MergeOne(p, a, n, len);//p合并到a
  51. }
  52. else
  53. {
  54. MergeOne(a, p, n, len);//a合并到p
  55. }
  56. len = len * 2;//增加有序序列长度
  57. f = 1 - f;//使f值在0和1之间切换
  58. count++;
  59. cout << "第" << count << "步排序:";
  60. print(a, n);
  61. }
  62. if (f) {//如果进行了排序
  63. for (h = 0; h < n; h++)//将内存p中的数据复制到数组a中
  64. a[h] = p[h];
  65. }
  66. free(p);//释放内存
  67. }

 

 

八、递归排序

编写sort()函数将一组无序数排列成降序,要求利用递归算法来实现外层循环,主函数中对数据{5,3,7,4,2,9,8,32,54,21,6,43}调用sort()函数实现排序。

  1. void sort(int *x, int n) {
  2. int j, t;
  3. if (n == 1)
  4. return;
  5. for ( j = 0; j < n; j++)
  6. {
  7. if (x[0] < x[j]) {
  8. t = x[0];
  9. x[0] = x[j];
  10. x[j] = t;
  11. }
  12. }
  13. sort(x + 1, n - 1);
  14. }
  15. int main() {
  16. int a[12] = { 5,3,7,4,2,9,8,32,54,21,6,43 };
  17. sort(a, 12);
  18. for (int k = 0; k < 12; k++)
  19. cout << a[k] << ' ';
  20. cout << endl;
  21. return 0;
  22. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/608038
推荐阅读
相关标签
  

闽ICP备14008679号