排序算法-快排

    今天聊聊排序算法,排序算法平時也會用到,有很多比如,冒泡,快排,選擇,歸併排序等.今天就聊一聊快速排序算法排序算法的一個宗旨就是經過一趟排序,何爲一趟排序呢?就是遍歷完一次數組,數組中的一部分數據比另外一部分的數據都要小.當然這兩部分數據內部仍然是無序的,然後我們再對這兩部分數據分別進行排序,如此遞歸下去.所以整個算法的核心思想就是這樣,今天介紹兩種實現快速排序的方法,一種是交換排序以及另一種方法(這種我也叫不出來方法),大家看代碼就能看明白.

    首先看第一種方法,

void quickSort1(vector<int> &nums, int left, int right){
    if (left<right){
        int key = nums[left], low = left+1, high = right;
        while (low<=high){   //爲什麼是<=
            while (low<high && nums[low]>key && nums[high]<key)
                swap(nums[low++], nums[high--]);
            if (nums[low]<=key) low++;
            if (nums[high]>=key) high--;
        }
        swap(nums[left], nums[high]); //爲什麼是和high位置交換
        quickSort1(nums, left, high-1);
        quickSort1(nums, high+1, right);
    }
}
    因爲算法是從兩個端點向中間收縮,所以我們要確保left<right,首先我們選取一個key值,等完成一趟排序之後,key左邊的元素統統小於key右邊的元素,然後再從key處割裂開,左右兩邊分別進行以上算法.然後定義low爲左邊的起始點,high爲右邊的起始點.如果滿足第一個while條件,就相當於左邊的數值大,右邊的數值小,然後我們交換一下兩者,同時把low和high接着往中間走一步,再繼續比較.當不符合條件時,我們跳出當前while循環,然後執行下面兩個判斷,這兩個判斷的目的是爲了防止產生死循環,如果沒有這兩句話,當nums[low]=key或者當nums[high]==key時,不符合上面的while循環,是不是就陷入了死循環.當退出while循環時,high<=low而且nums[low]>key,而且這一個過程中key值一直沒動,我們需要把他放在合適的位置,此時nums[low]>key,那key還能和low位置的值交換嗎?好像不可以了,那爲什麼和high位置的值交換呢,如果我們在第一個循環中設置low<high,那麼high的最小值就是low,所以也不能和high位置的值交換,那如果我們設置爲low<=high時,結束while循環時high位置就在low-1處,所以key和這個位置的值交換.這樣就完成了一趟遍歷,接下來,就從high處把數組割裂開,然後對兩段數組分別排序即可.

    第二種方法:代碼如下

void quickSort2(vector<int> &v, int left, int right){
    if (left < right){
        int key = v[left], low = left, high = right;
        while (low < high){
            while (low < high && v[high] >= key)
                high--;
            if (low < high)
                v[low++] = v[high];
            while (low < high && v[low] <= key)
                low++;
            if (low < high)
                v[high--] = v[low];
        }
        v[low] = key;
        quickSort2(v, left, low-1);
        quickSort2(v, low+1, right);
    }
}
        這種方法就比較好理解了,先從右邊遍歷數組,直到遇到一個比key值小的,然後把這個值放到low位置處,low指向下一個位置,這時數組中有兩個v[high]了,在low位置處(前面)的這個是正確的位置,在high處這個位置是不正確的位置.然後從左邊開始向右遍歷,直到遇到一個比key值大的數值,然後把他放到右邊的high位置處,這時是不是數組中有了兩個v[low]了,前面這個位置是不正確的,所以要把key值放到這個位置.接着從low處割裂開,然後對兩段數組進行排序.

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章