鱼C论坛

 找回密码
 立即注册
查看: 1397|回复: 0

[技术交流] 排序算法_期末复习笔记

[复制链接]
发表于 2022-7-24 09:54:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
头文件
  1. #include <stdio.h>
  2. #include <string>
复制代码



直接插入排序
  1. //直接插入排序(普通版本)
  2. void InsertSort0(int A[], int n)
  3. {
  4.         int i, j, temp;
  5.         for (i = 1; i < n; i++)
  6.         {
  7.                 if (A[i] < A[i - 1])
  8.                 {
  9.                         temp = A[i];
  10.                         for (j = i - 1; j >= 0 && A[j] > temp; --j)
  11.                         {
  12.                                 A[j + 1] = A[j];
  13.                         }
  14.                         A[j + 1] = temp;
  15.                 }
  16.         }
  17. }

  18. //直接插入排序(带哨兵)
  19. void InsertSort1(int A[], int n)
  20. {
  21.         int i, j;
  22.         for (i = 2; i <= n; i++)
  23.         {
  24.                 if (A[i] < A[i - 1])
  25.                 {
  26.                         A[0] = A[i];  //A[0]为哨兵,不带元素
  27.                         for (j = i - 1; A[0] < A[j]; --j)
  28.                         {
  29.                                 A[j + 1] = A[j];
  30.                         }
  31.                         A[j + 1] = A[0];
  32.                 }
  33.         }
  34. }
复制代码



折半插入排序
  1. //折半插入排序
  2. void InsertSort2(int A[], int n)
  3. {
  4.         int i, j, low, high, mid;
  5.         for (i = 2; i <= n; i++)
  6.         {
  7.                 A[0] = A[i];
  8.                 low = 1; high = i - 1;   //设置折半查找范围
  9.                 while (low <= high)
  10.                 {
  11.                         mid = (low + high) / 2;  //取中间点
  12.                         if (A[mid] > A[0])
  13.                         {
  14.                                 high = mid - 1;  //查找左半值表
  15.                         }
  16.                         else
  17.                         {
  18.                                 low = mid + 1;    //查找右半值表
  19.                         }
  20.                 }
  21.                 for (j = i - 1; j >= high + 1; j--)
  22.                 {
  23.                         A[j + 1] = A[j];   //统一后移元素,空出插入位置
  24.                 }
  25.                 A[high + 1] = A[0];  //插入操作
  26.         }
  27. }
复制代码



冒泡排序
  1. //冒泡排序
  2. //交换函数(可用于堆排序)
  3. void swap(int &a, int &b)
  4. {
  5.         int temp = a;
  6.         a = b;
  7.         b = temp;
  8. }

  9. //冒泡排序算法
  10. void BubbleSort(int A[], int n)
  11. {
  12.         for (int i = 0; i < n - 1; i++)
  13.         {
  14.                 bool flag = false;  //表示本趟冒泡是否发生交换的标志
  15.                 for (int j = n - 1; j > i; j--)
  16.                 {
  17.                         if (A[j - 1] > A[j])
  18.                         {
  19.                                 swap(A[j - 1], A[j]);
  20.                                 flag = true;
  21.                         }
  22.                 }
  23.                 if (flag == false)
  24.                 {
  25.                         return;
  26.                 }
  27.         }
  28. }
复制代码



快速排序
  1. //快速排序
  2. //满足条件左右划分函数
  3. int Partition(int A[], int low, int high)
  4. {
  5.         int pivot = A[low];
  6.         while (low < high)
  7.         {
  8.                 while (low < high && A[high] >= pivot)
  9.                 {
  10.                         --high;
  11.                 }
  12.                 A[low] = A[high];
  13.                 while (low < high && A[low] <= pivot)
  14.                 {
  15.                         ++low;
  16.                 }
  17.                 A[high] = A[low];
  18.         }
  19.         A[low] = pivot;
  20.         return low;
  21. }

  22. //快速排序算法
  23. void QuickSort(int A[], int low, int high)
  24. {
  25.         if (low < high)  //调出递归的条件
  26.         {
  27.                 int pivotpos = Partition(A, low, high);  //划分
  28.                 QuickSort(A, low, pivotpos - 1);
  29.                 QuickSort(A, pivotpos + 1, high);
  30.         }
  31. }
复制代码



简单选择排序
  1. //简单选择排序
  2. void SelectSort(int A[], int n)
  3. {
  4.         int i, j, min;
  5.         for (i = 0; i < n - 1; i++)
  6.         {
  7.                 min = i;
  8.                 for (j = i + 1; j < n; j++)
  9.                 {
  10.                         if (A[j] < A[min])
  11.                         {
  12.                                 min = j;
  13.                         }
  14.                 }
  15.                 if (min != i)
  16.                 {
  17.                         int temp = A[i];
  18.                         A[i] = A[min];
  19.                         A[min] = temp;
  20.                 }
  21.         }
  22. }
复制代码



堆排序
  1. //堆排序算法

  2. /*-----------------------------------------------------------
  3.   A是存储堆的数组,k是需要检查的结点小标,len是堆中结点个数
  4. -----------------------------------------------------------*/
  5. void AdjustDown(int A[], int k, int len)
  6. {
  7.         A[0] = A[k];   //A[0]暂存这个需要检查的结点值
  8.         /*------------------------------------------------------------------------------
  9.           从这个结点的左孩子开始往下比较,
  10.           如果发生交换,对交换过的结点继续和它的孩子比较
  11.         -------------------------------------------------------------------------------*/

  12.         for (int i = 2 * k; i <= len; i *= 2)
  13.         {
  14.                 if (i < len && A[i] < A[i + 1])  //如果右孩子大一些,只需要考虑和右孩子比较
  15.                 {
  16.                         i++;
  17.                 }
  18.                 if (A[0] >= A[i])  //如果这个结点的值不小于它的较大孩子结点值,则不需要交换
  19.                 {
  20.                         break;
  21.                 }
  22.                 else
  23.                 {
  24.                         A[k] = A[i];  //结点值则将较大的孩子结点值赋值给该结点
  25.                         k = i;  //从i开始,继续往下检查,直到所有及诶单检查结束
  26.                 }

  27.         }
  28.         A[k] = A[0];  //检查到最后k的值就是最后一轮交换过的结点位置下标,将该结点换过去
  29. }


  30. void BuildMaxHeap(int A[], int len)
  31. {
  32.         /*----------------------------------------------------------------
  33.                 由数组小标高处往低处,从第一个可能需要调整的非叶结点开始检查,
  34.                 直到根结点(注意根结点不是从0开始的,而是1)
  35.         ------------------------------------------------------------------*/
  36.         for (int i = len / 2; i > 0; i--)
  37.         {
  38.                 AdjustDown(A, i, len);
  39.         }
  40. }


  41. //算法实现
  42. void HeapSort(int A[], int len)
  43. {
  44.         BuildMaxHeap(A, len);//初始化建堆
  45.         for (int i = len; i > 1; i--)  //n-1趟的交换和建堆过程
  46.         {
  47.                 //输出对顶元素(和堆底元素交换)
  48.                 swap(A[i], A[1]);
  49.                 /*
  50.                 int temp = A[i];
  51.                 A[i] = A[1];
  52.                 A[1] = temp;
  53.                 */
  54.                 //printf(A[i]);
  55.                 AdjustDown(A, 1, i - 1); //把余下的i-1个元素整理成堆
  56.         }
  57. }
复制代码



归并排序
  1. //归并排序

  2. /*-------------------------------------------------------
  3. 思想:
  4.         表A的两段A[low...mid]和A[mid+1...high]各自有序,
  5.         将它们合并成一个有序表
  6. --------------------------------------------------------*/
  7. void Merge(int A[], int low, int mid, int high)
  8. {
  9.         //辅助数组B
  10.         int *B = (int *)malloc((high + 1) * sizeof(int));

  11.         int i, j, k;
  12.         for (k = low; k <= high; k++)
  13.         {
  14.                 B[k] = A[k];  //将A的元素复制到B中
  15.         }
  16.         for (i = low, j = mid + 1, k = i; i <= mid && j <= high; k++)  //k是归并之后数组的下标计数器
  17.         {
  18.                 if (B[i] <= B[j])  //比较B的左右两段中的元素
  19.                 {
  20.                         A[k] = B[i++];  //将最小值复制到A中
  21.                 }
  22.                 else
  23.                 {
  24.                         A[k] = B[j++];
  25.                 }
  26.                
  27.         }
  28.         while (i <= mid)  //若第一个表未检测完,直接将剩下的元素复制过来
  29.         {
  30.                 A[k++] = B[i++];
  31.         }
  32.         while (j <= high)  //若第二个表未检测完,直接将剩下的元素复制过来
  33.         {
  34.                 A[k++] = B[j++];
  35.         }
  36. }

  37. //归并排序算法实现
  38. void MergeSort(int A[], int low, int high)
  39. {
  40.         if (low < high)
  41.         {
  42.                 int mid = (low + high) / 2;  //从中间划分两个子序列
  43.                 MergeSort(A, low, mid);   //从左侧子序列进行归并排序
  44.                 MergeSort(A, mid + 1, high);  //从右侧子序列进行归并排序
  45.                 Merge(A, low, mid, high); //归并为一个数组
  46.         }
  47. }
复制代码



辅助函数
  1. //测试数组打印的结果是否满足需求
  2. void ArryShow(int A[], int n)
  3. {
  4.         for (int i = 0; i < n; i++)
  5.         {
  6.                 printf("%d  ", A[i]);
  7.         }
  8.         printf("\n");
  9. }
复制代码



main函数
  1. int main()
  2. {

  3.         printf("\n------直接插入排序(普通版)------\n");
  4.         int A0[] = { 49,38,65,97,76,13,27,49 };
  5.         printf("\n排序前:"); ArryShow(A0, 8);
  6.         InsertSort0(A0, 8);
  7.         printf("\n排序后:"); ArryShow(A0, 8);


  8.         printf("\n------直接插入排序(带哨兵)------\n");
  9.         int A1[] = { 55,23,45,78,97,11,24,65 };
  10.         printf("\n排序前:"); ArryShow(A1, 8);
  11.         InsertSort1(A1, 7);
  12.         printf("\n排序后:"); ArryShow(A1, 8);


  13.         printf("\n------折半插入排序------\n");
  14.         int A2[] = { 34,45,67,12,31,89,95,87 };
  15.         printf("\n排序前:"); ArryShow(A2, 8);
  16.         InsertSort2(A2, 7);
  17.         printf("\n排序后:"); ArryShow(A2, 8);


  18.         printf("\n------冒泡排序------\n");
  19.         int A3[] = { 1,4,8,7,3,6,2,5 };
  20.         printf("\n排序前:"); ArryShow(A3, 8);
  21.         BubbleSort(A3, 8);
  22.         printf("\n排序后:"); ArryShow(A3, 8);

  23.         printf("\n------快速排序------\n");
  24.         int A4[] = { 32,23,56,42,88,79,67,55 };
  25.         printf("\n排序前:"); ArryShow(A4, 8);
  26.         QuickSort(A4, 0, 7);
  27.         printf("\n排序后:"); ArryShow(A4, 8);

  28.         printf("\n------简单选择排序------\n");
  29.         int A5[] = { 23,45,89,87,54,45,32,66 };
  30.         printf("\n排序前:"); ArryShow(A5, 8);
  31.         SelectSort(A5, 8);
  32.         printf("\n排序后:"); ArryShow(A5, 8);


  33.         printf("\n------堆排序------\n");
  34.         int A6[] = { -1,52,45,23,100,45,92 };
  35.         printf("\n排序前:"); ArryShow(A6, 7);
  36.         HeapSort(A6, 6);
  37.         printf("\n排序后:"); ArryShow(A6, 7);


  38.         printf("\n------归并排序------\n");
  39.         int A7[] = { 49,38,65,97,76,13,27 };
  40.         printf("\n排序前:"); ArryShow(A7, 7);
  41.         MergeSort(A7, 0,6);
  42.         printf("\n排序后:"); ArryShow(A7, 7);


  43.         return 0;
  44. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-11 01:58

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表