白话排序算法(选择,插入,冒泡)

排序算法是算法中的基础,今天我来用自己的话说下三种最基本的算法,理解了这三种基本的算法就可以进一步学习怎么优化排序算法了。呵呵,废话不多说,咱们开始。

简单选择排序算法:

简单选择排序的基本思想是:一次选定数组中的一个数,记下当前位置并假设它是从当前位置开始后面数中的最小数min=i,从这个数的下一个数开始扫描直到最后一个数,并记录下最小数的位置min,扫描结束后如果min不等于i,说明假设错误,则交换min与i位置上数。(也即:每次从数列中找出一个最小的数放到最前面来,再从剩下的n-1个数中选择一个最小的,不断做下去。)

通俗的话说:你要在你的班上选择女朋友,(假定你有这个权利的话),你开始肯定会最喜欢的,然后再选择次喜欢的,然后继续在剩下的MM中找你比较喜欢的。这样就可以按你的要求排成一个序了,就这样理解。

简单选择排序算法的关键:1.每一趟在n-i+1中选取最小的记录 2.通过n-i次关键字进行比较 3.总共需要n(n-1)/2次比较 4.选择排序算法的时间复杂度是“死”的,也就是O(n^2)

算法代码:

Code:
  1. #include<stdio.h>
  2. voidSelectSort(int*a,intlen)//简单选择排序算法*a为数组len为数组长度
  3. {
  4. inti,j,k;
  5. for(i=1;i<len;i++)//比较n-i次i为指向无序区的开始位置
  6. {
  7. j=i;
  8. for(k=i-1;j<len;j++)//k记下目前最小关键字的位置,每一轮进行比较取出最小值
  9. {
  10. if(a[j]<a[k])//如果排在前面的数字大于后面的就交换两者的key
  11. {
  12. k=j;
  13. }
  14. }
  15. if(k>=i)//一轮结束后,把k认为的最小值和i进行交换
  16. {
  17. intm;
  18. m=a[k];
  19. a[k]=a[i-1];
  20. a[i-1]=m;
  21. }
  22. }
  23. }
  24. intmain(void)
  25. {
  26. inta[10];
  27. while(true)
  28. {
  29. for(intn=0;n<10;n++)
  30. {
  31. printf("/n第%d数:",(n+1));
  32. scanf("%d",&a[n]);
  33. }
  34. SelectSort(a,10);
  35. for(inti=0;i<10;i++)//输出排序后的数
  36. {
  37. printf("%d",a[i]);
  38. }
  39. }
  40. }

插入排序:

插入排序基本思想是:假设待排序的记录存放在数组R[1..n]中。初始时,R[1]自成1个有序区,无序区为R[2..n]。从i=2起直至i=n为止,依次将R[i]插入当前的有序区R[1..i-1]中,生成含n个记录的有序区。

(也就是:每次从数列中取一个还没有取出过的数,并按照大小关系插入到已经取出的数中使得已经取出的数仍然有序。)

通俗的理解是:比如大家打牌的时候,每次抓到牌后放到适合的位置

算法代码:

Code:
  1. #include<stdio.h>
  2. voidInsertSort(int*a,intlen)
  3. {
  4. for(inti=1;i<len;i++)
  5. {
  6. intj=i,x=a[i];//x相当于中间变量,用于把key=i的值保存下来,用于后面交换
  7. while(j&&a[j-1]>x)//如果j为真且前面一个数大于后面一个数的话
  8. {
  9. a[j]=a[j-1],j--;//假如第一次排序的话,这边的a[j]=a[1],也即把前一个值大的给后面一个,并且j再减减,如果为0就退出
  10. }
  11. a[j]=x;//假如第一次排序的话,这边的a[j]=a[0],然后把x的值赋给它
  12. }
  13. }
  14. intmain(void)
  15. {
  16. inta[10];
  17. while(true)
  18. {
  19. for(intn=0;n<10;n++)
  20. {
  21. printf("/n第%d数:",(n+1));
  22. scanf("%d",&a[n]);
  23. }
  24. InsertSort(a,10);
  25. for(inti=0;i<10;i++)//输出排序后的数
  26. {
  27. printf("%d",a[i]);
  28. }
  29. }
  30. }

插入算法图示:

冒泡排序:

冒泡排序的基本思想:将被排序的记录数组R[1..n]垂直排列,每个记录R[i]看作是重量为R[i].key的气泡。根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R:凡扫描到违反本原则的轻气泡,就使其向上"飘浮"。如此反复进行,直到最后任何两个气泡都是轻者在上,重者在下为止。

(也即:分为若干趟进行,每一趟排序从前往后比较每两个相邻的元素的大小(因此一趟排序要比较n-1对位置相邻的数)并在每次发现前面的那个数比紧接它后的数大时交换位置;进行足够多趟直到某一趟跑完后发现这一趟没有进行任何交换操作(最坏情况下要跑n-1趟,这种情况在最小的数位于给定数列的最后面时发生)。事实上,在第一趟冒泡结束后,最后面那个数肯定是最大的了,于是第二次只需要对前面n-1个数排序,这又将把这n-1个数中最小的数放到整个数列的倒数第二个位置。这样下去,冒泡排序第i趟结束后后面i个数都已经到位了,第i+1趟实际上只考虑前n-i个数(需要的比较次数比前面所说的n-1要小)。这相当于用数学归纳法证明了冒泡排序的正确性:实质与选择排序相同。)

通俗的说:在排队时,按个子高的和个子矮的进行比较,两两进行比较

代码实现:

Code:
  1. #include<stdio.h>
  2. voidBubbletSort(int*a,intlen)//*a传进来的数组len为数组的长度
  3. {
  4. intm;
  5. for(boolbSwap=true;bSwap;len--)
  6. {
  7. bSwap=false;//当下面不满足时退出循环
  8. for(intj=1;j<len;j++)
  9. {
  10. if(a[j-1]>a[j])//交换值
  11. {
  12. m=a[j];
  13. a[j]=a[j-1];
  14. a[j-1]=m;
  15. bSwap=true;
  16. }
  17. }
  18. }
  19. }
  20. intmain(void)
  21. {
  22. inta[10];
  23. while(true)
  24. {
  25. for(intn=0;n<10;n++)
  26. {
  27. printf("/n第%d数:",(n+1));
  28. scanf("%d",&a[n]);
  29. }
  30. BubbletSort(a,10);
  31. for(inti=0;i<10;i++)//输出排序后的数
  32. {
  33. printf("%d",a[i]);
  34. }
  35. }
  36. }

冒泡演示图:

大家是不是想,选择排序和冒泡排序差不多哈,那他们的区别是哪呢?

冒泡算法,每次比较如果发现较小的元素在后面,就交换两个相邻的元素。而选择排序算法的改进在于:先并不急于调换位置,先从A[1]开始逐个检查,看哪个数最小就记下该数所在的位置P,等一躺扫描完毕,再把A[P]和A[1]对调,这时A[1]到A[10]中最小的数据就换到了最前面的位置。所以,选择排序每扫描一遍数组,只需要一次真正的交换,而冒泡可能需要很多次。比较的次数是一样的。

一般是选择排序的平均时间复杂度比冒泡排序的稍低:

.................................若大家有什么有关问题可以提出,谢谢!。。。。

下面是 用自己语言理解排序算法(希尔排序) 【二】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值