C语言中的排序算法--冒泡排序,选择排序,希尔排序

冒泡排序Bubble Sort,台湾译为:泡沫排序气泡排序)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端

维基百科:点击打开链接

[cpp] view plain copy

  1. /*
  2. 用选择法对10个数进行排序
  3. */
  4. #include<stdio.h>
  5. void main()
  6. {
  7. int i,j,a[10];
  8. for(i=0;i<10;i++)
  9. scanf("%d",&a[i]);
  10. for(i=0;i<9;i++)
  11. {//n个数要进行n-1趟比较
  12. for(j=0;j<=9-i;j++)          //每趟比较n-i次
  13. if(a[j]>a[j+1])          //依次比较两个相邻的数,将小数放在前面,大数放在后面
  14. {
  15. int t=a[j];
  16. a[j]=a[j+1];
  17. a[j+1]=t;
  18. }
  19. }
  20. for(i=0;i<10;++i)               //输出比较之后的数组
  21. printf(" %d",a[i]);
  22. }

另一种常见的写法

[cpp] view plain copy

  1. /*
  2. 冒泡排序的另外一种写法
  3. */
  4. #include<stdio.h>
  5. void BubbleSort(int a[],int n)
  6. {
  7. int i,j;
  8. for(i=n-1;i>0;--i)          //从n-1循环的到0,也是n次
  9. for(j=0;j<i;j++)
  10. if(a[j]>a[j+1])
  11. {
  12. int temp=a[j];
  13. a[j]=a[j+1];
  14. a[j+1]=temp;
  15. }
  16. }
  17. void main()
  18. {
  19. int a[10],i;
  20. for(i=0;i<10;i++)
  21. scanf("%d",&a[i]);
  22. BubbleSort(a,10);
  23. printf("排序后的数组:\n");
  24. for(i=0;i<10;i++)
  25. printf(" %d",a[i]);
  26. }

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾(目前已被排序的序列)。以此类推,直到所有元素均排序完毕。

[cpp] view plain copy

  1. #include<stdio.h>
  2. void SelectSort(int a[],int n)
  3. {
  4. int i,j;
  5. for(i=0;i<n-1;i++)              //n个数要进行n-1趟比较,每次确定一个最小数放在a[i]中
  6. {
  7. int k=i;                    //假设a[0]是最小的数,把下标0放在变量K里面,
  8. for(j=i+1;j<n;j++)
  9. if(a[k]>a[j])  k=j;     //如果a[k]>a[j] 前面的数比后面的数大,交换下标,此时k指向小的数
  10. if(k!=i)
  11. {
  12. int temp=a[i];
  13. a[i]=a[k];
  14. a[k]=temp;
  15. }
  16. }
  17. }
  18. void main()
  19. {
  20. int a[10],i;
  21. for(i=0;i<10;i++)
  22. scanf("%d",&a[i]);
  23. SelectSort(a,10);
  24. printf("排序后的数组:\n");
  25. for(i=0;i<10;i++)
  26. printf(" %d",a[i]);
  27. }

希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步。然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。

假设有一个很小的数据在一个已按升序排好序的数组的末端。如果用复杂度为O(n2)的排序(冒泡排序或插入排序),可能会进行n次的比较和交换才能将该数据移至正确位置。而希尔排序会用较大的步长移动数据,所以小数据只需进行少数比较和交换即可到正确位置。

一个更好理解的希尔排序实现:将数组列在一个表中并对列排序(用插入排序)。重复这过程,不过每次用更长的列来进行。最后整个表就只有一列了。将数组转换至表是为了更好地理解这算法,算法本身仅仅对原数组进行排序(通过增加索引的步长,例如是用i += step_size而不是i++)。

例如,假设有这样一组数[ 13 14 94 33 82 25 59 94 65 23 45 27 73 25 39 10 ],如果我们以步长为5开始进行排序,我们可以通过将这列表放在有5列的表中来更好地描述算法,这样他们就应该看起来是这样:

13 14 94 33 82
25 59 94 65 23
45 27 73 25 39
10

然后我们对每列进行排序:

10 14 73 25 23
13 27 94 33 39
25 59 94 65 82
45

当我们以单行来读取数据时我们得到:[ 10 14 73 25 23 13 27 94 33 39 25 59 94 65 82 45 ].这时10已经移至正确位置了,然后再以3为步长进行排序:

10 14 73
25 23 13
27 94 33
39 25 59
94 65 82
45

排序之后变为:

10 14 13
25 23 33
27 25 59
39 65 73
45 94 82
94

最后以1步长进行排序(此时就是简单的插入排序了)。

[cpp] view plain copy

  1. //希尔排序
  2. #include<stdio.h>
  3. #define LT(a,b) ((a)<(b))
  4. #define MAX_SIZE 20
  5. #define T 3
  6. #define N 10
  7. typedef int KeyType;
  8. typedef int InfoType;
  9. typedef struct
  10. {
  11. KeyType key;
  12. InfoType otherinfo;
  13. }RedType;
  14. typedef struct
  15. {
  16. RedType r[MAX_SIZE+1];
  17. int length;
  18. }SqList;
  19. void PrintSqList(SqList L)
  20. {
  21. int i;
  22. for(i=1;i<L.length;i++)
  23. {
  24. printf("(%d %d)",L.r[i].key,L.r[i].otherinfo);
  25. }
  26. printf("\n");
  27. }
  28. int   PrintSqlListKey(SqList L)
  29. {
  30. int i;
  31. for(i=1;i<L.length;i++)
  32. {
  33. printf("%d ",L.r[i].key);
  34. }
  35. printf("\n");
  36. return 0;
  37. }
  38. void ShellInsert(SqList &L,int dk)
  39. {
  40. int i,j;
  41. for(i=dk+1;i<=L.length;i++)
  42. {
  43. if LT(L.r[i].key,L.r[i-dk].key)
  44. {
  45. L.r[0]=L.r[i];
  46. for(j=i-dk;j<0&& LT(L.r[i].key,L.r[j].key);j-=dk)
  47. {
  48. L.r[j+dk]=L.r[j];
  49. }
  50. L.r[j+dk]=L.r[0];
  51. }
  52. }
  53. }
  54. void ShellSort(SqList &L,int dlta[],int t)
  55. {
  56. int k;
  57. for(k=0;k<t;k++)                                  //对所有增量序列
  58. {
  59. ShellInsert(L,dlta[k]);
  60. printf("dlta[%d]=%d,第%d趟排序结果(仅输出关键字):",k,dlta[k],k+1);
  61. PrintSqlListKey(L);
  62. }
  63. }
  64. void main()
  65. {
  66. RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,65},{13,6},{27,7},{49,8},{55,9},{4,10}};
  67. SqList m;
  68. int i,dt[T]={5,3,1};
  69. for(i=0;i<N;i++)
  70. {
  71. m.r[i+1]=d[i];
  72. }
  73. m.length=N;
  74. printf("希尔排序前:\n");
  75. PrintSqList(m);
  76. printf("\n");
  77. ShellSort(m,dt,T);
  78. printf("希尔排序后:\n");
  79. PrintSqList(m);
  80. printf("\n");
  81. }
时间: 2024-07-31 14:34:47

C语言中的排序算法--冒泡排序,选择排序,希尔排序的相关文章

排序算法(六)——希尔排序

基本思想 希尔排序是基于插入排序的,又叫缩小增量排序. 在插入排序中,标记符左边的元素是有序的,右边的是没有排过序的,这个算法取出标记符所指向的数据,存入一个临时变量,接着,在左边有序的数组中找到临时变量应该插入的位置,然后将插入位置之后的元素依次后移一位,最后插入临时变量中的数据. 试想,假如有一个很小的数据项在靠近右端的位置上,把这个数据项插入到有序数组中时,将会有大量的中间数据项需要右移一位,这个步骤对每一个数据项都执行了将近N次复制.虽然不是所有数据项都必须移动N个位置,但是,数据项平均

简单排序算法 冒泡排序 选择排序 插入排序

冒泡排序: 总体思路:对未排序的各个元素,依次比较两个元素,如果这两个元素为逆序(与想要的顺序相反),则交换这两个元素. 这样可以有两种排序的思路: 思路一: 固定位置排序:比如有一个未排序队列,下标依次为0,1,2,.....N-1, 第一轮排序:首先固定位置0,将下标为0的元素依次和下标为1.下标为2.....下标为N-1的元素相比较,若相比较的两个元素为逆序,则交换这两个元素,这样第一轮排序完之后,位置为0的元素,就是最大的(最小的). 第二轮排序:首先固定位置1,将下标为1的元素依次和下

经典排序算法学习笔记四——希尔排序

一.希尔排序 数据结构 数组 最差时间复杂度 根据步长序列的不同而不同.已知最好的:O(n*log ^{2}n) 最优时间复杂度 O(n) 平均时间复杂度 根据步长序列的不同而不同. 最差空间复杂度 O(n) 1.算法思想: 先取一个正整数d1<n,把所有序号相隔d1的数组元素放一组,组内进行直接插入排序: 然后取d2<d1,重复上述分组和排序操作: 直至di=1,即所有记录放进一个组中排序为止. 我是栗子,栗子,栗子 假设有这样一组数[ 13 14 94 33 82 25 59 94 65

1)③排序算法之插入排序[2]希尔排序

1 #include<iostream> 2 using namespace std; 3 4 int shell_sort(int n,int array[100]){//希尔排序法 5 register int dh,temp,i,j; 6 dh=n/2; 7 while(dh>=1){ 8 for( i=dh;i<n;i++){ 9 temp=array[i]; 10 j=i-dh; 11 while(j>=0&&array[j]>temp){ 1

排序算法1——插入排序,希尔排序

插入排序: #include <iostream> using namespace std; void insert(int *arry, int lo, int current) { while (lo >= 0 && arry[lo] < current) { arry[lo + 1] = arry[lo]; lo--; } arry[lo + 1] = current; } void print(int *arry, int size) { for (int

C语言排序算法之简单交换法排序,直接选择排序,冒泡排序

C语言排序算法之简单交换法排序,直接选择排序,冒泡排序,最近考试要用到,网上也有很多例子,我觉得还是自己写的看得懂一些. 简单交换法排序 1 /*简单交换法排序 2 根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置 3 交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动 4 不稳定 5 */ 6 #include<windows.h> 7 #include<stdio.h> 8 void main(){ 9 int i,j,arr[10

STL中排序算法的选择

 当大多数程序员需要对一组对象进行排序的时候,首先想到的一个算法是sort.sort是一个非常不错的算法,但它也并非在任何场合下都是完美无缺的.有时候我们并不需要一个完全的排序操作.比如说,如果我们有一个存放Widget的矢量,而我们希望将质量最好的20个Widget送给最重要的顾客,按照顾客的重要程度送上不同质量的Widget,那么只需要排序出前20个最好的Widget,其他的Widget可以不用排序.在这种情况下,需要的是一种部分排序的功能,而有一个名为partial_sort的算法正好

Java中的经典算法之选择排序(SelectionSort)

Java中的经典算法之选择排序(SelectionSort) a) 原理:每一趟从待排序的记录中选出最小的元素,顺序放在已排好序的序列最后,直到全部记录排序完毕.也就是:每一趟在n-i+1(i=1,2,…n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录.基于此思想的算法主要有简单选择排序.树型选择排序和堆排序.(这里只介绍常用的简单选择排序) b) 简单选择排序的基本思想:给定数组:int[] arr={里面n个数据}:第1趟排序,在待排序数据arr[1]~arr[n]中选出最小的数

排序算法—冒泡排序

*/--> 排序算法-冒泡排序 Table of Contents 1 问题描述 2 冒泡排序(Bubble) 2.1 冒泡排序(一) 2.2 冒泡排序(二) 2.3 冒泡排序(三) 2.4 冒泡排序(四) 3 阅读参考 1 问题描述 引子 排序是数据结构中十分重要的一章,排序算法有很多种,一直没时间整理而且很多排序算法理解的也不是很透彻.希望通过这次整理吃透吧! 排序算法十分多,故分篇进行整理. 说明 本文重点是理解排序算法,而不是完整的程序,所以每节都只有具体排序算法的接口.没有完整的源代码

排序算法总结------选择排序 ---javascript描述

每当面试时避不可少谈论的话题是排序算法,上次面试时被问到写排序算法,然后脑袋一懵不会写,狠狠的被面试官鄙视了一番,问我是不是第一次参加面试,怎么可以连排序算法都不会呢?不过当时确实是第一次去面试,以此恶补排序算法. 一.基本排序算法:基本排序算法有冒泡排序,选择排序,插入排序. 选择排序算法思想:选择排序从数组的头开始,将第一个元素与其他元素进行比较,找到最小的元素,然后放到数组的第一个位置.然后再从第二个元素开始找比他小的元素,放到第二个位置,以此类推,重复上述步骤,当进行到数组的第二个位置时