[C语言] 8种排序

[复制链接]
 楼主| 一路向北lm 发表于 2018-8-8 10:14 | 显示全部楼层 |阅读模式
TI, ST, os, ge, POS

转过来的8种排序
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. //冒泡排序
  4. void bubleSort(int data[], int n);
  5. //快速排序
  6. void quickSort(int data[], int low, int high);
  7. int findPos(int data[], int low, int high);
  8. //插入排序
  9. void bInsertSort(int data[], int n);
  10. //希尔排序
  11. void shellSort(int data[], int n);
  12. //选择排序
  13. void selectSort(int data[], int n);
  14. //堆排序
  15. void heapSort(int data[], int n);
  16. void swap(int data[], int i, int j);
  17. void heapAdjust(int data[], int i, int n);
  18. //归并排序
  19. void mergeSort(int data[], int first, int last);
  20. void merge(int data[], int low, int mid, int high);
  21. //基数排序
  22. void radixSort(int data[], int n);
  23. int getNumPos(int num, int pos);

  24. int main() {
  25.     int data[10] = {43, 65, 4, 23, 6, 98, 2, 65, 7, 79};
  26.     int i;
  27.     printf("原先数组:");
  28.     for(i=0;i<10;i++) {
  29.         printf("%d    ", data[i]);
  30.     }
  31.     printf("\n");
  32.     printf("冒泡排序:");
  33.     bubleSort(data, 10);
  34.     for(i=0;i<10;i++) {
  35.         printf("%d    ", data[i]);
  36.     }
  37.     printf("\n");
  38.     printf("快速排序:");
  39.     quickSort(data, 0, 9);
  40.     for(i=0;i<10;i++) {
  41.         printf("%d    ", data[i]);
  42.     }
  43.     printf("\n");
  44.     printf("插入排序:");
  45.     bInsertSort(data,10);
  46.     for(i=0;i<10;i++) {
  47.         printf("%d    ", data[i]);
  48.     }
  49.     printf("\n");
  50.     printf("希尔排序:");
  51.     shellSort(data, 10);
  52.     for(i=0;i<10;i++) {
  53.         printf("%d    ", data[i]);
  54.     }
  55.     printf("\n");
  56.     printf("选择排序:");
  57.     selectSort(data, 10);
  58.     for(i=0;i<10;i++) {
  59.         printf("%d    ", data[i]);
  60.     }
  61.     printf("\n");
  62.     /*int data[11] = {-1, 43, 65, 4, 23, 6, 98, 2, 65, 7, 79};
  63.     int i;
  64.     printf("原先数组:");
  65.     int data[11] = {-1, 43, 65, 4, 23, 6, 98, 2, 65, 7, 79};
  66.     for(i=1;i<11;i++) {
  67.         printf("%d    ", data[i]);
  68.     }
  69.     printf("\n");
  70.     printf(" 堆排序:");
  71.     heapSort(data, 10);
  72.     for(i=1;i<11;i++) {
  73.         printf("%d    ", data[i]);
  74.     }
  75.     printf("\n");
  76.     printf("归并排序:");
  77.     mergeSort(data, 0, 9);
  78.     for(i=0;i<10;i++) {
  79.         printf("%d    ", data[i]);
  80.     }
  81.     printf("\n");*/
  82.     printf("基数排序:");
  83.     radixSort(data, 10);
  84.     for(i=0;i<10;i++) {
  85.         printf("%d    ", data[i]);
  86.     }
  87.     printf("\n");
  88.     return 0;
  89. }

  90. /*--------------------冒泡排序---------------------*/
  91. void bubleSort(int data[], int n) {
  92.     int i,j,temp;
  93.     //两个for循环,每次取出一个元素跟数组的其他元素比较
  94.     //将最大的元素排到最后。
  95.     for(j=0;j<n-1;j++) {
  96.         //外循环一次,就排好一个数,并放在后面,
  97.         //所以比较前面n-j-1个元素即可
  98.         for(i=0;i<n-j-1;i++) {
  99.             if(data[i]>data[i+1]) {
  100.                 temp = data[i];
  101.                 data[i] = data[i+1];
  102.                 data[i+1] = temp;
  103.             }
  104.         }
  105.     }  
  106. }

  107. /*--------------------快速排序---------------------*/
  108. int findPos(int data[], int low, int high) {
  109.     //将大于t的元素赶到t的左边,大于t的元素赶到t的右边
  110.     int t = data[low];
  111.     while(low < high) {
  112.         while(low < high && data[high] >= t) {
  113.             high--;
  114.         }
  115.         data[low] = data[high];
  116.         while(low < high && data[low] <=t) {
  117.             low++;
  118.         }
  119.         data[high] = data[low];
  120.     }
  121.     data[low] = t;
  122.     //返回此时t在数组中的位置
  123.     return low;
  124. }
  125. //在数组中找一个元素,对大于该元素和小于该元素的两个数组进行再排序
  126. //再对两个数组分为4个数组,再排序,直到最后每组只剩下一个元素为止
  127. void quickSort(int data[], int low, int high) {
  128.     if(low > high) {
  129.         return;
  130.     }
  131.     int pos = findPos(data, low, high);
  132.     quickSort(data, low, pos-1);
  133.     quickSort(data, pos+1, high);
  134. }

  135. /*--------------------插入排序---------------------*/
  136. void bInsertSort(int data[], int n) {
  137.     int low,high,mid;
  138.     int temp,i,j;
  139.     for(i=1;i<n;i++) {
  140.         low = 0;
  141.         //把data[i]元素插入到它的前面data[0-(i-1)]中
  142.         temp =data[i];
  143.         high = i-1;
  144.         //该while是折半,缩小data[i]的范围(优化手段)
  145.         while(low <= high) {
  146.             mid = (low+high)/2;
  147.             if(data[mid] > temp) {
  148.                 high = mid-1;
  149.             }
  150.             else {
  151.                 low = mid+1;
  152.             }
  153.         }
  154.         int j = i;
  155.         //让data与已经排序好的数组的各个元素比较,小的放前面
  156.         while((j > low) && data[j-1] > temp) {
  157.             data[j] = data[j-1];
  158.             --j;
  159.         }
  160.         data[low] = temp;
  161.     }
  162. }

  163. /*--------------------希尔排序---------------------*/
  164. void shellSort(int * data, int n) {
  165.     int step,i,j,key;
  166.     //将数组按照step分组,不断二分到每组只剩下一个元素
  167.     for(step=n/2;step>0;step/=2) {
  168.         //将每组中的元素排序,小的在前
  169.         for(i=step;i<n;i++) {
  170.             key = data[i];
  171.             for(j=i-step;j>=0 && key<data[j];j-=step) {
  172.                 data[j+step] = data[j];
  173.             }
  174.             //和上面的for循环一起,将组中小的元素换到数组的前面
  175.             data[j+step] = key;
  176.         }
  177.     }
  178. }

  179. /*--------------------选择排序---------------------*/
  180. void selectSort(int data[], int n) {
  181.     int i,j,mix,temp;
  182.     //每次循环数组,找出最小的元素,放在前面,前面的即为排序好的
  183.     for(i=0;i<n-1;i++) {
  184.         //假设最小元素的下标
  185.         int mix = i;
  186.         //将上面假设的最小元素与数组比较,交换出最小的元素的下标
  187.         for(j=i+1;j<n;j++) {
  188.             if(data[j] < data[mix]) {
  189.                 mix = j;
  190.             }
  191.         }
  192.         //若数组中真的有比假设的元素还小,就交换
  193.         if(i != mix) {
  194.             temp = data[i];
  195.             data[i] = data[mix];
  196.             data[mix] = temp;
  197.         }
  198.     }
  199. }

  200. /*--------------------堆排序---------------------*/
  201. //堆排序将数组先组成二叉树,默认从数组的data[1]开始排,data[0]是
  202. //无效数据
  203. void heapSort(int data[], int n) {
  204.     int i;
  205.     //先将数组组成一棵完全二叉树
  206.     //从2/n开始,就是从倒数第二排结点往前开始
  207.     for(i=n/2;i>0;i--) {
  208.         heapAdjust(data, i, n);
  209.     }
  210.     //循环每个结点,将大的结点交换到堆顶
  211.     for(i=n;i>1;i--) {
  212.         swap(data, 1, i);
  213.         //每次交换完都要调整二叉树,将剩下的最大的结点交换到堆顶
  214.         heapAdjust(data, 1, i-1);
  215.     }
  216. }
  217. //交换函数
  218. void swap(int data[], int i, int j) {
  219.     int temp;
  220.     temp = data[i];
  221.     data[i] = data[j];
  222.     data[j] = temp;
  223. }
  224. void heapAdjust(int data[], int i, int n) {
  225.     int j, temp;
  226.     //假设第一个结点的元素是最大的
  227.     temp = data[i];
  228.     //i结点:2*i是i结点的左结点,2*i+1是i结点的右结点
  229.     //把结点元素大的交换到前面
  230.     for(j=2*i;j<=n;j*=2) {
  231.         if(j < n && data[j] < data[j+1]) {
  232.             j++;
  233.         }
  234.         if(temp >= data[j]) {
  235.             break;
  236.         }
  237.         data[i] = data[j];
  238.         i = j;
  239.     }
  240.     data[i] = temp;
  241. }

  242. /*--------------------归并排序---------------------*/
  243. void mergeSort(int data[], int first, int last) {
  244.     int mid = 0;
  245.     //将数组不停的二分分组再组合,直到每组只剩一个元素
  246.     if(first < last) {
  247.         mid = (first+last)/2;
  248.         mergeSort(data, first, mid);
  249.         mergeSort(data, mid+1, last);
  250.         merge(data, first, mid, last);
  251.     }
  252.     return;
  253. }
  254. void merge(int data[], int low, int mid, int high) {
  255.     int i, k;
  256.     //定义一个临时数组存放传进来的无序数组排好序之后的数组
  257.     int *temp = (int *)malloc((high-low+1)*sizeof(int));
  258.     //将无序数组分成两个序列
  259.     int left_low = low;
  260.     int left_high = mid;
  261.     int right_low = mid+1;
  262.     int right_high = high;
  263.     //将两个序列比较排序,小的排前
  264.     for(k=0;left_low<=left_high && right_low<=right_high;k++) {
  265.         if(data[left_low]<=data[right_low]) {
  266.             temp[k] = data[left_low++];
  267.         }
  268.         else{
  269.             temp[k] = data[right_low++];
  270.         }
  271.     }
  272.     //左序列如果有剩下元素未排序,加到临时数组的末尾
  273.     if(left_low <= left_high) {
  274.         for(i=left_low;i<=left_high;i++) {
  275.             temp[k++] = data[i];
  276.         }
  277.     }
  278.     //右序列如果有剩下元素未排序,加到临时数组的末尾
  279.     if(right_low <= right_high) {
  280.         for(i=right_low;i<=right_high;i++) {
  281.             temp[k++] = data[i];
  282.         }
  283.     }
  284.     //将排好序的小分组转移到原数组中
  285.     for(i=0;i<high-low+1;i++) {
  286.         data[low+i] = temp[i];
  287.     }
  288.     free(temp);
  289.     return;
  290. }
  291. /*--------------------基数排序---------------------*/
  292. //该函数的作用是找出num的pos位数的数字(比如:23的个位数数字是3)
  293. int getNumPos(int num, int pos) {
  294.     int i;
  295.     int temp = 1;
  296.     for(i=0;i<pos-1;i++) {
  297.         temp *= 10;
  298.     }
  299.     return (num / temp) % 10;
  300. }
  301. void radixSort(int data[], int n) {
  302.     int i,j,k,pos,num,index;
  303.     //这几句话是创建一个从0-9(行)× (n+1)(列)的网格,第一列从上往下是0-9,
  304.     //第二列是该行包含的元素个数,默认为0个
  305.     int *radixArrays[10];
  306.     for(i=0;i<10;i++) {
  307.         radixArrays[i] = (int *)malloc(sizeof(int) * (n+1));
  308.         radixArrays[i][0] = 0;
  309.     }
  310.     //pos最大为31为数,计算机能承受的最大范围了
  311.     for(pos=1;pos<=31;pos++) {
  312.         //该for循环是将数组的元素按照位数(pos)的值放进网格内
  313.         for(i=0;i<n;i++) {
  314.             num = getNumPos(data[i], pos);
  315.             index = ++radixArrays[num][0];
  316.             radixArrays[num][index] = data[i];
  317.         }
  318.         //该for循环是将上面的for循环已经按照某个位数(pos)排列好的元素存入数组
  319.         for(i=0,j=0;i<10;i++) {
  320.             for(k=1;k<=radixArrays[i][0];k++) {
  321.                 data[j++] = radixArrays[i][k];
  322.             }
  323.             //清空网格,以便给下个位数排列
  324.             radixArrays[i][0] = 0;
  325.         }
  326.     }
  327. }


yediezeus 发表于 2018-8-8 11:34 | 显示全部楼层
airwill 发表于 2018-8-8 19:47 | 显示全部楼层
好东西, 需要顶一下.
初步看了一下, 好象没有发现哪个的效率特别高一点

评论

研究一下  发表于 2018-8-9 08:31
您需要登录后才可以回帖 登录 | 注册

本版积分规则

293

主题

3837

帖子

81

粉丝
快速回复 在线客服 返回列表 返回顶部