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

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

    比如一个无序的序列a[7]:

    4 6 8 9 3 1 5

    l:0  r:6

    现在我们要对它做降序排列

    1. 定义两个位置标记l和r在要排序部分的左右两边,(这里是0号和6号),  先选定第一个元素4作为一个比较的基准值,

    2.然后从右往左找一个大于4的数,这里是5。然后把右标记指向5也就是a[6],(其实原来的j就标记了这)。这时我们把r和l标记的两个数a[r]和a[l]交换。交换完成后,就变成了这样:

    5 6 8 9 3 1 4 

    l:0  r:6

    3. 然后从左到右找一个小于4的数,这里是3。然后让左标记指向它,然后交换a[l]与a[r]。交换完成后,就变成了这样:

    5 6 8 9 4 1 3

    l:4  r:6

    然后重复第2步,让 r 从现在的位置向左移动找到一个大于4的数,这时我们发现l和r相遇了,这样我们就得到了一个特殊的数组----以元素4为界,它左边的数总是大于4的,它右边的数总是小于4的。这时我们把数组取出2份,左边一份是所有大于4的数,是a[0]~a[3]。然后右边一份是所有小于4的数,a[5]~a[6]。

    然后我们分别让这两个子序列进行上面的操作:

    对于左边部分a[0]~a[3]:5 6 8 9

    选定左边第一个数a[0],也就是5为基准值,然后让所有比5大的数都在5左边,让所有比5小的数都在5右边。

    得到:6 8 9 5

    然后再继续分,递归地执行这个过程(让所有比基准值大的数都在基准值左边,所有比基准值小的数都在基准值右边),然后直到不能再分了。

    这时我们就能得到一个降序的序列。

    具体实现如下:

     1 //LR表示要排序部分的左右边界,如果要排序一个10个元素的数组,就调用QuickSort(0,10);
     2 void QuickSort(int L, int R)        
     3 {
     4     //设置两下标,分别为要排序部分的开始和结束元素的数组下标
     5     int l = L, r = R - 1;    
     6     if (l >= r) return;
     7     int key = a[L];            //以序列第一个元素为基准
     8     while (l < r)
     9     {
    10         //让右边的下标r从右往左找到第一个小于key的数
    11         while (a[r] <= key&&r>l) r--;//从右往左找到一个比key大的值
    12         swap(&a[r], &a[l]);        //交换左右两个下标位置的值
    13         if (l == r)break;        //如果l等于r,就结束循环
    14         //让左边的下标l从左往右找到第一个大于key的数
    15         while (a[l] >= key&&r>l)l++;//从左往右找到一个比key小的值
    16         swap(&a[r], &a[l]);        //交换左右两个下标位置的值
    17         if (l == r)break;        //如果l等于r,就结束循环
    18     }
    19     
    20     //上面的部分已经让r==l,
    21     //并且所有比key小的数都在key的左边,所有比key大的数都在key右边
    22     QuickSort(L, r);
    23     QuickSort(r+1, R);
    24 }

    上面代码是实现降序的,如果想实现升序,只要把两个while里面的>=和<=互换。

    这里有一个例子,随机生成50000个数,然后降序输出

    #include<stdio.h>
    #include<time.h>
    #include<stdlib.h>
    #define N 50000
    
    int a[N];
    
    void init()//初始化数组
    {
        srand((unsigned)time(NULL));
        for (int i = 0; i < N; i++)
        {
            a[i] = rand();
        }
    }
    void print()                //输出数组元素
    {
        int i;
        for (i = 0; i < N;i++)
            printf("%d ",a[i]);
        printf("
    ");
    }
    
    void swap(int*a, int*b)//交换两个变量的值
    {
        int c = *a;
        *a = *b;
        *b = c;
    }
    
    //LR表示要排序部分的左右边界,如果要排序一个10个元素的数组,就调用QuickSort(0,10);
    void QuickSort(int L, int R)        
    {
        //设置两下标,分别为要排序部分的开始和结束元素的数组下标
        int l = L, r = R - 1;    
        if (l >= r) return;
        int key = a[L];            //以数组第一个元素为基准
        while (l < r)
        {
            //让右边的下标r从右往左找到第一个小于key的数
            while (a[r] <= key&&r>l) r--;
            swap(&a[r], &a[l]);        //交换左右两个下标位置的值
            if (l == r)break;        //如果l等于r,就结束循环
            //让左边的下标l从左往右找到第一个大于key的数
            while (a[l] >= key&&r>l)l++;
            swap(&a[r], &a[l]);        //交换左右两个下标位置的值
            if (l == r)break;        //如果l等于r,就结束循环
        }
        
        //上面的部分已经让r==l,
        //并且所有比key小的数都在key的左边,所有比key大的数都在key右边
        QuickSort(L, r);
        QuickSort(r+1, R);
    }
    
    int main()
    {
        init();
        printf("数组原来是这样的:
    ");
        print();
        QuickSort(0,N);
        printf("
    排序后:
    ");
        print();
        system("pause");
    }
  • 相关阅读:
    ISpout源码解析
    storm完全分布式部署
    sqoop工具
    sqoop安装步骤
    HBASE常用配置
    linux命令无法使用:命令行输入:set>lll cat lll echo $PATH
    BubbleSort
    QuickSortWithRec
    面试题
    Nginx配置安装
  • 原文地址:https://www.cnblogs.com/hjw1/p/7842504.html
Copyright © 2011-2022 走看看