程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> “chaos”的算法--之快速排序

“chaos”的算法--之快速排序

編輯:關於C語言

聲明:版權所有,歡迎轉載。 聯系信箱:[email protected]

今天下午在公司不是太忙,又總結了一個排序類算法,算是偷了點懶,主要還是快排。快速排序實際上是最常用的一種排序算法了,就像名字一樣、速度快,效率高。快排是基於冒泡排序而來的。整體來說,在最壞情況是每次劃分選取的基准都是當前無序區中關鍵字最小(或最大)的記錄,劃分的結果是基准左邊的子區間為空(或右邊的子區間為空),而劃分所得的另一個非空的子區間中記錄數目,僅僅比劃分前的無序區中記錄個數減少一個。時間復雜度為O(n*n)在最好情況下,每次劃分所取的基准都是當前無序區的"中值"記錄,劃分的結果是基准的左、右兩個無序子區間的長度大致相等。總的關鍵字比較次數:O(nlgn)盡管快速排序的最壞時間為O(n2),但就平均性能而言,它是基於關鍵字比較的內部排序算法中速度最快者,快速排序亦因此而得名。它的平均時間復雜度為O(nlgn)。


快排思想:

快速排序是C.R.A.Hoare於1962年提出的一種劃分交換排序。它采用了一種分治的策略,通常稱其為分治法(Divide-and-ConquerMethod)。


1) 分治法的基本思想

 分治法的基本思想是:將原問題分解為若干個規模更小但結構與原問題相似的子問題。遞歸地解這些子問題,然後將這些子問題的解組合為原問題的解。


2)快速排序的基本思想

 設當前待排序的無序區為R[low..high],利用分治法可將快速排序的基本思想描述為:

①分解:

 在R[low..high]中任選一個記錄作為基准(Pivot),以此基准將當前無序區劃分為左、右兩個較小的子區間R[low..pivotpos-1)和R[pivotpos+1..high],並使左邊子區間中所有記錄的關鍵字均小於等於基准記錄(不妨記為pivot)的關鍵字pivot.key,右邊的子區間中所有記錄的關鍵字均大於等於pivot.key,而基准記錄pivot則位於正確的位置(pivotpos)上,它無須參加後續的排序。

注意:

 劃分的關鍵是要求出基准記錄所在的位置pivotpos。劃分的結果可以簡單地表示為(注意pivot=R[pivotpos]):

 R[low..pivotpos-1].keys≤R[pivotpos].key≤R[pivotpos+1..high].keys

其中low≤pivotpos≤high。

②求解:

  通過遞歸調用快速排序對左、右子區間R[low..pivotpos-1]和R[pivotpos+1..high]快速排序。

③組合:

 因為當"求解"步驟中的兩個遞歸調用結束時,其左、右兩個子區間已有序。對快速排序而言,"組合"步驟無須做什麼,可看作是空操作。

該段摘自http://student.zjzk.cn/course_ware/data_structure/web/paixu/paixu8.3.2.1.htm)

或許這樣說還不是太直觀,那就用白話再說一遍吧。快速排序是找出一個元素理論上可以隨便找一個)作為基准(pivot),然後對數組進行分區操作,使基准左邊元素的值都不大於基准值,基准右邊的元素值 都不小於基准值,如此作為基准的元素調整到排序後的正確位置。遞歸快速排序,將其他n-1個元素也調整到排序後的正確位置。最後每個元素都是在排序後的正 確位置,排序完成。所以快速排序算法的核心算法是分區操作,即如何調整基准的位置以及調整返回基准的最終位置以便分治遞歸。

舉例說明一下吧,這個可能不是太好理解。假設要排序的序列為

2 2 4 9 3 6 7 1 5 首先用2當作基准,使用i j兩個指針分別從兩邊進行掃描,把比2小的元素和比2大的元素分開。首先比較2和5,5比2大,j左移

2 2 4 9 3 6 7 1 5 比較2和1,1小於2,所以把1放在2的位置

2 1 4 9 3 6 7 1 5 比較2和4,4大於2,因此將4移動到後面

2 1 4 9 3 6 7 4 5 比較2和7,2和6,2和3,2和9,全部大於2,滿足條件,因此不變

經過第一輪的快速排序,元素變為下面的樣子

[1] 2 [4 9 3 6 7 5]之後,在把2左邊的元素進行快排,由於只有一個元素,因此快排結束。右邊

進行快排,遞歸進行,最終生成最後的結果。

#include <stdio.h>
#include <stdlib.h>
void quickSort(int array[], int start, int end)
{
     if(start < end)
     {
         int key = array[start];
         int low = start;
         int high = end;
         while(low < high)
         {
                while((low < high) && key < array[high])
                    high--;
                array[low] = array[high];
                while((low < high) && key > array[low])
                    low++;
                array[high] = array[low];
         }
         array[low] = key;
         quickSort(array, start, low - 1);
         quickSort(array, low + 1, end);
     }
}
int main(int argc, char *argv[])
{
    int index = 0;
    int array[] = {2, 4, 9, 3, 6, 7, 1, 5};
    quickSort(array, 0, 7);
    for(; index < 8; index++)
    {
          printf("%d\t", array[index]); 
    }
    system("pause");
    return 0;
}

本文出自 “驿落黃昏” 博客,請務必保留此出處http://yiluohuanghun.blog.51cto.com/3407300/1266266

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved