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

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

简单选择排序算法:

简单选择排序的基本思想是:一次选定数组中的一个数,记下当前位置并假设它是从当前位置开始后面数中的最小数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. void SelectSort(int *a,int len)//简单选择排序算法 *a为数组 len为数组长度  
  3. {   
  4.     int i,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.             int m;   
  18.             m = a[k];   
  19.             a[k] = a[i-1];   
  20.             a[i-1] = m;   
  21.         }   
  22.     }   
  23. }   
  24. int main(void)   
  25. {   
  26.     int a[10];   
  27.     while(true)   
  28.     {   
  29.         for(int n=0;n<10;n++)   
  30.         {   
  31.             printf("/n第 %d 数:",(n+1));   
  32.             scanf("%d",&a[n]);   
  33.         }   
  34.         SelectSort(a,10);   
  35.         for(int i=0;i<10;i++)//输出排序后的数  
  36.         {   
  37.             printf("%d ",a[i]);   
  38.         }   
  39.     }   
  40.   
  41. }   

 插入排序:

插入排序基本思想是:假设待排序的记录存放在数组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. void InsertSort(int *a,int len)   
  3. {   
  4.     for (int i=1;i<len;i++)   
  5.     {   
  6.         int j=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. }   
  15. int main(void)   
  16. {   
  17.     int a[10];   
  18.     while(true)   
  19.     {   
  20.         for(int n=0;n<10;n++)   
  21.         {   
  22.             printf("/n第 %d 数:",(n+1));   
  23.             scanf("%d",&a[n]);   
  24.         }   
  25.         InsertSort(a,10);   
  26.         for(int i=0;i<10;i++)//输出排序后的数  
  27.         {   
  28.             printf("%d ",a[i]);   
  29.         }   
  30.     }   
  31.   
  32. }   

 

 插入算法图示:

冒泡排序:

冒泡排序的基本思想:将被排序的记录数组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. void BubbletSort(int*a,int len)//*a传进来的数组 len为数组的长度  
  3. {   
  4.     int m;   
  5.     for (bool bSwap=true;bSwap;len--)   
  6.     {   
  7.         bSwap = false;//当下面不满足时退出循环  
  8.         for (int j=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.   
  21. int main(void)   
  22. {   
  23.     int a[10];   
  24.     while(true)   
  25.     {   
  26.         for(int n=0;n<10;n++)   
  27.         {   
  28.             printf("/n第 %d 数:",(n+1));   
  29.             scanf("%d",&a[n]);   
  30.         }   
  31.         BubbletSort(a,10);   
  32.         for(int i=0;i<10;i++)//输出排序后的数  
  33.         {   
  34.             printf("%d ",a[i]);   
  35.         }   
  36.     }   
  37.   
  38. }   

 冒泡演示图:

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

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

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

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

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


原文链接: http://blog.csdn.net/crazyjixiang/article/details/6465713

转载于:https://my.oschina.net/chen106106/blog/51193

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值