zoukankan      html  css  js  c++  java
  • 快速排序算法

        它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。

        设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它左边,所有比它大的数都放到它右边,这个过程称为一趟快速排序。

    算法是:

    1)设置两个变量I、J,排序开始的时候:I=0,J=N-1;
    2)以第一个数组元素作为关键数据,赋值给key,即 key=A[0];
    3)从J开始向前搜索,即由后开始向前搜索(J=J-1),找到第一个小于key的值A[J],并与key交换;(我看有的小伙伴会问为什么要从右开始,不从左开始。因为我们一般是选取第一个数即最左边的数字作为关键元素,也就是基准数,其余的都要与它相比较,所以就是从最后一个数字即最右边开始比较)
    4)从I开始向后搜索,即由前开始向后搜索(I=I+1),找到第一个大于key的A[I],与key交换;
    5)重复第3、4、5步,直到 I=J; (3,4步是在程序中没找到时候j=j-1,i=i+1,直至找到为止。
    找到并交换的时候i, j指针位置不变。另外当i=j这过程一定正好是i+或j-完成的最后另循环结束。) 

    来实践一下吧:(都跟基准数去比较)

    也有小伙伴会说,为什么第一个数字这么恰巧就是最中间的数呢?其实在设计这组数据我也是故意这样设置的,看起来比较方便(最优情况)。当然平时的数据,可不是让我们用上帝视角来解决的,但解决的方法都一样,一样的步骤。但是交换次数会多一些,但是总体时间复杂度相对还是比较低的(快速排序的平均时间复杂度也是:O(nlogn);最优的情况下空间复杂度为:O(logn)  ;每一次都平分数组的情况。 最差的情况下空间复杂度为:O( n )  ;退化为冒泡排序的情况)。

    排序法

    最差时间分析 平均时间复杂度 稳定度 空间复杂度
    冒泡排序 O(n2) O(n2) 稳定 O(1)
    快速排序 O(n2) O(n*log2n) 不稳定 O(log2n)~O(n)
    选择排序 O(n2) O(n2) 不稳定 O(1)
    二叉树排序 O(n2) O(n*log2n) 不一顶 O(n)

    插入排序

    O(n2) O(n2) 稳定 O(1)
    堆排序 O(n*log2n) O(n*log2n) 不稳定 O(1)
    希尔排序 O O 不稳定 O(1)

     实现代码:

    #include<stdio.h>
     
    // 打印数组
     void print_array(int *array, int length)
     {
         int index = 0;
         printf("array:
    ");
         for(; index < length; index++){
             printf(" %d,", *(array+index));
         }   
         printf("
    
    ");
     }
     
     void quickSort(int array[], int length)
     {
         int start = 0;
         int end = length-1;
         int value = array[start];// 得到哨兵元素
     
         if (1 > length) return;// 递归出口
     
         while(start < end){// 以哨兵元素为标准,分成大于它和小于它的两列元素
     
             while(start < end){// 从数组尾部往前循环得到小于哨兵元素的一个元素
                 if ( array[end--] < value ){
                     array[start++] = array[++end];
                     break;
                 }   
             }   
     
             while( start < end ){// 从数组头部往后循环得到大于哨兵元素的一个元素
                 if( array[start++] > value){
                     array[end--] = array[--start];
                     break;
                 }   
             }   
         }   
    
         array[start] = value;// 放置哨兵元素
         printf("
    start:%d, end:%d
    ", start, end);// 这个是测试下start和end是否一样
         quickSort(array, start);// 递归排序小于哨兵元素的那一列元素
         quickSort(array + start + 1, length - start - 1);// 递归排序大于哨兵元素的那一列
     }
     
     int main(void)
     {
         int array[7] = {15,8,12,23,25,6,36};
         print_array(array, 7);// 开始前打印下
         quickSort(array, 7);// 快速排序
         print_array(array, 7);// 排序后打印下
         return 0;
     }
  • 相关阅读:
    Linux mint OS
    Patroni 修改配置
    0x10
    01
    split
    IO流18 --- RandomAccessFile实现数据的读写操作 --- 技术搬运工(尚硅谷)
    IO流16 --- 对象流操作字符串 --- 技术搬运工(尚硅谷)
    IO流15 --- 数据流操作Java语言的基本数据类型 --- 技术搬运工(尚硅谷)
    IO流14 --- 打印流的使用 --- 技术搬运工(尚硅谷)
    JDBC2 --- 获取数据库连接的方式二 --- 技术搬运工(尚硅谷)
  • 原文地址:https://www.cnblogs.com/zpp1/p/12969564.html
Copyright © 2011-2022 走看看