• 常用排序算法之--快速排序


    个人认为,数据结构与算法是部分程序员的软肋,而对于非科班出身的程序员来说,更是软肋中的软肋。

    纠其原因,大部分是因为作为应用层面的程序开发,算法(尤其是查找算法)并不是影响程序性能的最关键的因素。同时作为一个完整的系统,从数据存储到获取都提供了

    相应的调用接口,如果要获取数据,我们只需要调用外部接口就可以了。模块化、工厂化导致了我们对算法的依赖降低了。依赖降低了,就导致这部分知识的退化。只是在找工作的时候,又得重拾这部分代码。唉,不说了,要不然又该挨广大园友们喷了。

    欢迎与广大朋友交流学习,qq:792911374

    网上介绍快速排序的文章很多,个人认为比较优秀的有:

    http://blog.csdn.net/morewindows/article/details/6684558

    http://developer.51cto.com/art/201403/430986.htm

    下面的内容,适合于看完了上面两篇文章后,思路清晰,但在编写代码过程中又有些疑惑的朋友们.....

    其实快速排序算法,就是以一个特定的元素作为基准值,把比它大的元素放在左边,比它小的元素放在右边。第一回快排后,形成的结果是基准值右边的元素都比基准值大,左边的元素都比基准值小。然后把基准值左边和右边的元素分别递归调用快排函数,进行周而复始的排序工作。

    需要注意的两点是:

    1、基准值要取快排函数中的low(最低索引)的元素,不能取索引为0的元素,博主就是在代码过程中一时疏忽取了0值,桑心了好几个小时^_^

    2、high一定是数组元素数减1,从0开始的嘛,地球人都知道的。

    编译与调试环境为:qt, c语言代码

    上代码:

      1 #include <QCoreApplication>
      2 #include <stdlib.h>
      3 #include <time.h>
      4 //数组数量
      5 const int ARRAY_NUM = 10;
      6 const int CHAR_NUM = 20;
      7 //结构类型信息
      8 struct RecordInfo{
      9     char name[CHAR_NUM];
     10     int key;
     11 };
     12 
     13 //生成待排数组
     14 void genrateArrayList(struct RecordInfo recList[]);
     15 //快速排序主体函数
     16 void quickSort(struct RecordInfo recList[], int low, int high);
     17 //打印排好序的数组
     18 void printArrayList(struct RecordInfo recList[]);
     19 
     20 int main(int argc, char *argv[])
     21 {
     22     QCoreApplication a(argc, argv);
     23     //待排序数组
     24     struct RecordInfo info[ARRAY_NUM];
     25     //生成待排序数组
     26     genrateArrayList(info);
     27     printf("排序之前的顺序为:
    ");
     28     //打印待排数组
     29     printArrayList(info);
     30     //数组排序
     31     quickSort(info, 0, ARRAY_NUM-1);
     32     printf("排序之后的顺序为:
    ");
     33     //打印数组内容
     34     printArrayList(info);
     35     return a.exec();
     36 }
     37 
     38 /**
     39   * @函数名:genrateArrayList
     40   * @参数:recList[]要生成的数组
     41   * @返回值:无
     42   * @用途:生成待排数组
     43   * @作者:yangfy
     44   */
     45 void genrateArrayList(struct RecordInfo recList[])
     46 {
     47     for(int i = 0; i < ARRAY_NUM; i++){
     48         if(i % 3 == 0 && i > 0){
     49             recList[i].key = recList[i - 3].key;
     50         }
     51         else{
     52             //srand(time(NULL));
     53             //生成ARRAY_NUM以内的随机数
     54             recList[i].key = rand() % ARRAY_NUM;
     55         }
     56         snprintf(recList[i].name, CHAR_NUM - 1, "第%d个元素。", i);
     57     }
     58 }
     59 
     60 /**
     61   * @函数名:quickSort
     62   * @参数:recList[]待排数组
     63   *       low:排序的开始元素索引
     64   *       high:排序的结束元素索引
     65   * @返回值:无
     66   * @用途:快速排序主体函数
     67   * @作者:yangfy
     68   */
     69 void quickSort(struct RecordInfo recList[], int low, int high)
     70 {
     71     //高值如果等于低值,则退出不用比较了。
     72     if(low < high){
     73         int i = low, j = high;
     74         //枢轴记录(也就是记录被覆盖之前的值),通常是第1个元素
     75         struct RecordInfo pivotInfo;
     76         pivotInfo = recList[low];
     77         while (i < j) {
     78             //找到比基准值小的索引
     79             while (i < j && recList[j].key >= pivotInfo.key)
     80                 j--;
     81             if(i < j){
     82                 //把j的值赋予i,同时把i加1
     83                 recList[i++] = recList[j];
     84             }
     85             //找到比基准值大的元素
     86             while (i < j && recList[i].key <= pivotInfo.key) {
     87                 i++;
     88             }
     89             if(i < j){
     90                 //把i的值赋予j,同时把j减1
     91                 recList[j--] = recList[i];
     92             }
     93         }
     94         //把准值赋予i,此时i左边的元素比基准值小,右边的比基准值大
     95         recList[i] = pivotInfo;
     96         //对基准值左边的元素进行递归排序,除去基准值i
     97         quickSort(recList, low, i - 1);
     98         //对基准值右边的元素进行递归排序,除去基准值i
     99         quickSort(recList, i + 1, high);
    100     }
    101 }
    102 /**
    103   * @函数名:printArrayList
    104   * @参数:recList[] 要打印的数组
    105   * @返回值:无
    106   * @用途:打印数组
    107   * @作者:yangfy
    108   */
    109 void printArrayList(struct RecordInfo recList[])
    110 {
    111     for(int i = 0; i < ARRAY_NUM; i++){
    112         printf("第%d个元素的索引为:%d, ->:%s
    ", i, recList[i].key, recList[i].name);
    113     }
    114 }

    运后结果:

    最后肿结:

    通过代码的运行结果可以看出,索引(key值)为1的4个元素,插入的先后顺序变成:0,9,3,6;改为了原来的0, 3, 6, 9的顺序。所以快速排序是不稳定的排序算法。

    快排算法也看着之前网上的介绍及代码写过一次,始终是不得要领,这次是看完算法思路,把网页关了。自已动手写代码,遇到问题再进行分析。真是蛮拼的了。标准的算法代码,网上很多,但如何了解要领,还需要每个小伙伴们仔细斟酌,认真思考了。

  • 相关阅读:
    iOS开发拓展篇—音频处理(音乐播放器1)
    iOS开发拓展篇—CoreLocation地理编码
    iOS开发拓展篇—CoreLocation定位服务
    iOS开发拓展篇—CoreLocation简单介绍
    iOS开发拓展篇—封装音频文件播放工具类
    图标框架Font Awesome
    WordPress基础:设置后台语言
    使用帝国备份王备份还原网站数据
    WordPress主题开发:加载脚本和样式
    WordPress主题开发:get_term_by和get_term_link
  • 原文地址:https://www.cnblogs.com/scud001/p/4419891.html
Copyright © 2020-2023  润新知