分治思想——快速排序算法

快速排序

官方說法:快速排序(Quicksort)是對冒泡排序的一種改進。快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然後再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。

通俗來說,就是不斷的挖坑和填坑

  • 1、其實就是先選擇一個基準數,然後這個基準數我們保存爲x,那它所在的位置就是一個空出來的坑。
  • 2、我們從右向左迭代,如果遇到比基準數小的數,就將其填到上次挖的坑中,然後它自己在的這個地方就變成了一個新的坑。
  • 3、然後再從左向右迭代,找比基準數大的數,將其填到上次挖的坑中,然後它所在的地方就變成了新的坑。
  • 4、最後要將基準數填入最後的坑中,然後將基準數所在的位置返回,方便下次調用時候使用
//挖坑填數
int adjustArray(int s[],int l, int r)   //傳入數組和左右的下標
{
    int i = l,j = r;    //分別表示左半邊的下標和右半邊的下標
    int x = s[l];       //默認最左邊的數就是挖的第一個坑
    while(i < j)        //要保證數組中元素最少有兩個
    {
        //從右向左迭代,找比基準數小的
        while(s[j] >= x && i < j)
            j--;
        if(i < j)        //找到了比基準數小的
        {
            s[i] = s[j];    //將其填到原來挖的坑的地方上,現在j處又形成了一個新的坑
            i++;            //i處填入了新的數,所以i++,然後從左往右去找,在左半邊比基準數大的數
        }

        //從左向右迭代去找比基準數大的
        while(s[i] < x && i < j)
            i++;
        if(i < j)
        {
            s[j] = s[i];
            j--;
        }
    }

    //退出時,要把坑用基準數填回去
    s[i] = x;
    return i;       //返回調整後基準數的位置,方便下一次遞歸調用的時候
}

就這樣將原來的數組以返回的基準數所在的位置爲中心,分成了兩個數組(理論上兩個,但在內存中還是在一起挨着的),然後分別對新的兩個數組遞歸進行挖坑和填坑的操作,當先前指示數組左右兩邊的下標的變量左邊的大於或等於(一般都是等於)右邊的時候(即數組已經被分的不能被分了),這時候原數組就變成有序的了,因爲按照上面的思路,所有左邊的都小於右邊的,那既然數組都被分的變成一個數一個小數組那就是左邊的數比右邊的數小,即有序,排序完成!

void quick_sort(int s[], int l, int r)
{
    if(l < r)
    {
        int i = adjustArray(s,l,r);
        //不能將上次的基準數拉入新的兩個數組中的任何一個,因爲其所在的位置已經是最終對的位置了,它左邊的數都比它小,右邊的都比它大
        quick_sort(s,l,i-1);        
        quick_sort(s,i+1,r);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章