一步一步写算法(之非递归排序)

来源:互联网 发布:想做淘宝兼职 编辑:程序博客网 时间:2024/06/07 00:07

原贴地址: http://blog.csdn.net/feixiaoxing/article/details/6844826

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

  

    在上面一篇博客当中,我们发现普通查找和排序查找的性能差别很大。作为一个100万的数据,如果使用普通的查找方法,那么每一个数据查找平均下来就要几十万次,那么二分法的查找呢,20多次就可以搞定。这中间的差别是非常明显的。既然排序有这么好的效果,那么这篇博客中,我们就对排序算做一个总结。

    按照我个人的理解,排序可以分为两种:一种是非递归排序,它主要按照非递归的方法对数据进行排序,也就是说主要数据的移位和循环来完成;另外一种就是递归方法,我们在排列当前数据的时候首先把子数据排列有序,然后才会排列当前的数据。这种不断递归调用的方法就是递归排序。

    非递归排序的方法很多,这里主要介绍冒泡排序、插入排序、希尔排序;递归的方法也不少,这里介绍的方法是快速排序、归并排序和堆排序。排序的内容很多,本篇博客主要介绍非递归排序,递归排序的内容主要在下一节内容解决。

    (1)冒泡排序

    冒泡排序的内容并不复杂。假设有n个数据需要排序,那么我们需要确定n个从大到小的数据,每一次都挑选第n大的数据是多少,并且放大相应的位置。直到所有的数据都排列整齐了,那么我们的排序就结束了。

[cpp] view plaincopy
  1. void bubble_sort(int array[], int length)  
  2. {  
  3.     int inner = 0, outer = 0;  
  4.     int median = 0;  
  5.   
  6.     if(NULL == array || 0 == length)  
  7.         return;  
  8.   
  9.     for(outer = length-1; outer >= 1; outer --){  
  10.         for(inner = 0; inner < outer; inner ++){  
  11.             if(array[inner] > array[inner + 1]){  
  12.                 median = array[inner];  
  13.                 array[inner] = array[inner + 1];  
  14.                 array[inner + 1] = median;  
  15.             }  
  16.         }  
  17.     }  
  18. }  
    那么这个程序有没有什么改进的地方呢?当然存在,如果发现在一次遍历循环之中,如果没有发生移位的现象,那么是不是可以判断这个排序可以结束了呢?朋友们可以好好思考一下这个问题?

[cpp] view plaincopy
  1. void bubble_sort(int array[], int length)  
  2. {  
  3.     int inner = 0, outer = 0;  
  4.     int median = 0;  
  5.     int flag = 1;  
  6.   
  7.     if(NULL == array || 0 == length)  
  8.         return;  
  9.   
  10.     for(outer = length-1; outer >= 1 && flag; outer --){  
  11.         flag = 0;  
  12.   
  13.         for(inner = 0; inner < outer; inner ++){  
  14.             if(array[inner] > array[inner + 1]){  
  15.                 median = array[inner];  
  16.                 array[inner] = array[inner + 1];  
  17.                 array[inner + 1] = median;  
  18.   
  19.                 if(flag == 0)  
  20.                     flag = 1;  
  21.             }  
  22.         }  
  23.     }  
  24. }  

    (2) 插入排序

    插入排序的意思就是说,我们把数据分成两个部分,一部分是已经排好序的数据,一部分是当前还没有完成排序的数据。那么这么说来的话,排序的过程是不是就是把没有排序的数据逐个插入到已经排好序的队列中的过程呢。大家可以自己先试一下,然后再看看我的代码对不对?

[cpp] view plaincopy
  1. void insert_sort(int array[], int length)  
  2. {  
  3.     int inner = 0;  
  4.     int outer = 0;  
  5.     int median = 0;  
  6.     if(NULL == array || 0 == length)  
  7.         return;  
  8.   
  9.     for(outer = 1; outer <length; outer ++){  
  10.         for(inner = outer; inner >= 1; inner --){  
  11.             if(array[inner] < array[inner -1]){  
  12.                 median = array[inner];  
  13.                 array[inner] = array[inner -1];  
  14.                 array[inner -1] = median;  
  15.             }else{  
  16.                 break;  
  17.             }  
  18.         }  
  19.     }  
  20. }  
    那么插入排序有没有像冒泡排序那样的改进方法呢?其实没有。因为每一次插入排序的位置都是局部比较的结果,而冒泡排序每一次的内容都是全局最优的。这从数据比较的次数就可以看出来。


    (3)希尔排序

    希尔排序,我个人认为可以看成是冒泡排序的变种。它的基本思想是:首先按照一个序列递减的方法逐渐进行排序。比如说有10个数据,我们按照序列5、3、1的顺序进行排序。首先是5,那么我们对1和6、2和7、3和8、4和9、5和10进行排列;第二轮是3,那么对数据1、4、7、10排列,再对2、5、8进行排列,以及3、6、9排列;第三轮就和冒泡排序一样了,以此对每个数据进行排列。它的优势就是让整个队列基本有序,减少数据移动的次数,从而降低算法的计算复杂度。

[cpp] view plaincopy
  1. void shell_sort(int array[], int length, int step)  
  2. {  
  3.     int inner = 0;  
  4.     int outer = 0;  
  5.     int median = 0;  
  6.   
  7.     if(NULL == array || 0 == length)  
  8.         return;  
  9.   
  10.     for(; step >= 1; step -=2){  
  11.         for(int index = 0; index < step; index ++){  
  12.             if((length -1) < (index + step))  
  13.                 continue;  
  14.             else{  
  15.                 outer = index + step;  
  16.                 while( (outer + step) <= (length - 1))  
  17.                     outer += step;  
  18.             }  
  19.   
  20.             for(;  outer >= (index + step);  outer -= step){  
  21.                 for(inner = index; inner <= outer - step; inner += step){  
  22.                     if(array[inner] >= array[inner + step]){  
  23.                         median = array[inner];  
  24.                         array[inner] = array[inner + step];  
  25.                         array[inner + step] = median;  
  26.                     }  
  27.                 }  
  28.             }  
  29.         }  
  30.     }  
  31. }  

总结:

    (1)上面的排序都是非递归程序,理解上不难,但是细节问题需要注意,特别是长度的问题

    (2)代码编写的时候务必注意测试用例的设计

    (3)如果可能的情况下,多使用已经验证的代码和函数


【预告: 下一篇博客介绍快速排序的内容】


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小米手机儿童模式忘记密码怎么办 小米应用锁密码忘了怎么办 小米air密码忘了怎么办 小米4密码忘了怎么办 小米手机开机密码忘了怎么办? 小米笔记本电脑开机密码忘了怎么办 小米笔记本开机密码忘了怎么办 htc手机忘记解锁图案怎么办 红米手机屏幕锁定怎么解锁怎么办 小米5s有id怎么办 手机密码找不回来了怎么办? 手机密码图案忘了怎么办 手机屏幕图案锁忘了怎么办 捡到苹果7有id锁怎么办 魅族什么都忘了怎么办 海信电视百事通登陆失败怎么办 去哪儿换号了怎么办 ipan充不进去电怎么办 安卓数据线松了怎么办 索尼z5耳机掉漆怎么办 索尼z5无限重启怎么办 苹果8基带坏了怎么办 oppo手机忘记图案密码怎么办 电池充不进去电怎么办 电脑充不进去电怎么办 苹果5c白苹果怎么办 港行不支持电信卡怎么办 安卓导航不开机怎么办 鞭炮放一半不响怎么办 禁止鸣笛的地方鸣笛了怎么办 手被炮仗炸了怎么办 手被猴子抓伤了怎么办 炸东西剩的油怎么办 炸臭豆腐剩的油怎么办 油炸久了油发黑怎么办 炸鱼的时候粘锅怎么办 吃了葱蒜有味怎么办 哺乳期喝了抹茶怎么办 干炸小黄鱼凉了怎么办 烧鱼酱油放多了怎么办 夏天腿干燥起皮怎么办