C/C++實現快速排序的兩種典型代碼


快速排序由C. A. R. Hoare在1960年提出。它的基本思想是:通過一趟排序將要排序的數據分割成獨立的兩部分,其中一部分的所有數據都比另外一部分的所有數據都要小,然后再按此方法對這兩部分數據分別進行快速排序,整個排序過程可以遞歸進行,以此達到整個數據變成有序序列。
第一種典型實現:通過兩個游標來遍歷整個待排序數組,i指向數組的第一個元素,j指向數組的最后一個元素。先取出數組中的一個數arr[i],將其保存在key中,此時arr[i]空出來了,這時游標j往前移,就可找到大於等於key的數,將其放到arr[i]中;然后游標i往后移,找到小於等於key的數,將其保存到arr[j]中;重復j往前移和i往后移的過程,直到i<j不滿足,此時i等於j,將key放到下標i處就完成了這輪排序。下標i之前的元素都小於arr[i],下標i之后的元素都大於arr[i]。最后用同樣的方式對分出來的左邊的小組和右邊的小組進行同上的做法就能使整個數組排序。

void sort(int *a, int left, int right)
{
    if(left >= right) /*如果左邊索引大於或者等於右邊的索引就代表已經整理完成一個組了*/
    {
        return ;
    }
    int i = left;
    int j = right;
    int key = a[left];
     
    while(i < j)                       /*控制在當組內尋找一遍*/
    {
        while(i < j && key <= a[j])
        /*而尋找結束的條件就是,1,找到一個小於或者大於key的數(大於或小於取決於你想升
        序還是降序)2,沒有符合條件1的,並且i與j的大小沒有反轉*/ 
        {
            j--;/*向前尋找*/
        }
         
        a[i] = a[j];
        /*找到一個這樣的數后就把它賦給前面的被拿走的i的值(如果第一次循環且key是
        a[left],那么就是給key)*/
         
        while(i < j && key >= a[i])
        /*這是i在當組內向前尋找,同上,不過注意與key的大小關系停止循環和上面相反,
        因為排序思想是把數往兩邊扔,所以左右兩邊的數大小與key的關系相反*/
        {
            i++;
        }
         
        a[j] = a[i];
    }
     
    a[i] = key;           /*當在當組內找完一遍以后就把中間數key回歸*/
    sort(a, left, i - 1); /*最后用同樣的方式對分出來的左邊的小組進行同上的做法*/
    sort(a, i + 1, right);/*用同樣的方式對分出來的右邊的小組進行同上的做法*/
                          /*當然最后可能會出現很多分左右,直到每一組的i = j 為止*/
}

第二種實現:在數組中隨便取一個數作為分開數組的標志,下面代碼將data[end]作為比較對象。通過游標index遍歷整個數組,找到比data[end]小的元素,先將small自增1,然后將下標index和small位置上的交換,即保存在small位置上。遍歷結束,下標small之前的數都比data[small]小,之后的數都大於等於data[small]。

void swap(int &a, int &b)
{
    int temp = a;
    a = b;
    b = temp;
}
int Partition(int data[], int length, int start, int end)
{
    if (data == nullptr || length <= 0 || start < 0 || end >= length)
        throw new std::exception("Invalid Parameters");

    int small = start - 1;
    for (int index = start; index < end; index++)
    {
        if (data[index] < data[end])
        {
            small++;/*small初始值是數組首元素位置的前一個位置,當找到比data[end]小的元素,先將small自增1,然后將下標index和small位置上的交換,即保存在small位置上。*/
            if (small != index)
                swap(data[index], data[small]);
        }
    }
    /*下標small之前的數都比data[small]小,之后的數都大於等於data[small]*/
    small++; 
    swap(data[small], data[end]);
    return small;
}
void Quicksort(int data[], int length, int start, int end)
{
    if(start == end)
        return;

    int index = Partition(data, length, start, end);
    if(index > start)
        Quicksort(data, length, start, index-1);
    if(index < end)
        Quicksort(data, length, index+1, end);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM