C語言:快速排序

來源:互聯網
上載者:User

標籤:原因   基於   長度   臨時   排序演算法   pre   等於   att   冒泡   

快速排序是排序演算法中,平均時間複雜度為O(n*log n)的一種演算法,其實現需要先解決這樣的一個問題,對一個序列A[1],A[2],A[3] .......A[N],調整序列中元素的位置,使得A[1](原序列中的第一個元素,下同)的左側所有元素都不超過A[1],右側所有元素都大於A[1],例如對序列{5,3,9,6,4,1}來說,調整後變為{3,1,4,5,9,6}這樣就讓A[1] =5 ,左側的所有元素,不超過它,右側的所有元素都大於它。

排序思想

1.快排是對冒泡排序的一種改進,在快速排序中,元素的比較和移動是從兩端向中間進行的,關鍵碼較大的元素一次就能從前面移動到後面,關鍵碼較小的元素一次就能從後面移動到前面,元素移動距離的較遠,從而減少了總的比較次數和移動次數

2.快速排序是基於分治法設計的,其分治策略是: 
①、劃分:選定一個元素作為軸值,以軸值為基準將整個序列劃分為兩個子序列。軸值的位置在劃分的過程中確定,並且前一個子序列的元素均小於或者等於軸值,後一個子序列的元素大於或者等於軸值

②、求解子問題:分別對劃分後的每一個子序列遞迴處理 
③、合并:由於對子序列的排序是就地進行的,所以合并並不需要執行任何操作

排序方法

1.選擇軸值,一般是選取第一個元素的關鍵碼。有一個快排的最壞情況就是如果待排序元素是正序或者逆序,就會將除軸值以外的元素分到軸值的一邊。 
2.劃分 
①、設定劃分區間:i=first,j=end 
②、執行右側掃描,直到r[j]小於軸值,將r[j]與r[i]交換,i++ 
③、執行左側掃描,直到r[i]大於軸值,將r[i]與r[j]交換,j– 
④、重複二到三直到i=j,確定看軸值的所在位置,返回該位置

 

初始索引值序列   23 12 35 6 19 50 28

一次劃分後    [19 13 6]    23  [35 50 28]

分別進行快速排序 [6 13]  19    [28]  35   [50]

          6  [13]             35 

             13    28        50

最終結果                6  13  19  23  28  35  50

 

 1 //對區間[left,right]進行劃分 2 int Partition(int A[],int left, int right) 3 { 4     int temp =A[left]; //存放到臨時變數temp 5  6     while(left < right) //只要left與right不相遇 7     { 8         while(left < right && A[right] > temp) right--;//反覆左移 9         A[left] = A[right];10 11         while(left < right && A[left] <= temp) left++;//反覆右移12         A[right] = A[left];13     }14 15     A[left] = temp;    //把temp放到right與left相遇的地方16     return left;    //返回相遇下標17 }

快速排序演算法當序列中元素的排列比較隨機時效率高,但是當序列中元素接近有序時,會達到最壞時間複雜度O(n^2),產生這種情況的主要原因在於主元沒有把當前區間劃分為兩個長度接近的子區間。有什麼辦法能解決這個問題呢?那就是隨機選取主元,這樣雖然演算法的最壞時間複雜度仍然是O(n^2)(例如,總是選擇A[left]為主元),但是對於任意輸入資料的期望時間複雜度都能達到O(n*log n),也就是說,不存在一組特定的資料能使這個演算法出現最壞情況。

 

 1 int randPartition(int A[],int left, int right) 2 { 3     //產生[left,right]內的隨機主元 4     int p = (round(1.0*rand()/RAND_MAX)*(right-left)+left); 5     swap(A[p],A[left]); 6     int temp =A[left]; 7     while(left < right) 8     { 9         while(left < right && A[right] > temp) right--;//反覆左移10         A[left] = A[right];11         while(left < right && A[left] <= temp) left++;//反覆右移12         A[right] = A[left];13     }14     A[left] = temp;15     return left;16 }

快速排序的遞迴實現如下:

 

 1 //快速排序,left與right初值為序列下標(例如 1 與 n) 2 void quicksort(int A[], int left, int right) 3 { 4     if(left < right) // 當前區間的長度超過1 5     { 6         //將[left,right]按A[right]一分為2 7         int pos = randPartition(A,left,right); 8         quicksort(A, left, pos-1);  //對左子區間遞迴進行快速排序 9         quicksort(A, pos+1, right); //對右子區間遞迴進行快速排序10     }11 }

 

C語言:快速排序

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.