您好,登錄后才能下訂單哦!
今天小編給大家分享一下C語言快速排序如何應用的相關知識點,內(nèi)容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
快速排序,說白了就是給基準數(shù)據(jù)找其正確索引位置的過程
希爾排序相當于直接插入排序的升級,他們屬于插入排序類;堆排序相當于簡單選擇排序的升級,他們同屬于選擇排序類;而對于交換排序類的冒泡排序升級版本就是快速排序。
通過一趟排序將待排記錄分割成獨立的兩部分,其中一部分記錄的關鍵字比另一部分記錄的關鍵字小,則可分別對這兩部分記錄繼續(xù)進行排序,以達到整個排序的目的。
首先設定一個分界值,通過該分界值將數(shù)組分成左右兩部分。
將大于或等于分界值的數(shù)據(jù)集中到數(shù)組右邊,小于分界值的數(shù)據(jù)集中到數(shù)組的左邊。此時,左邊部分中各元素都小于或等于分界值,而右邊部分中各元素都大于或等于分界值。
然后,左邊和右邊的數(shù)據(jù)可以獨立排序。對于左側的數(shù)組數(shù)據(jù),又可以取一個分界值,將該部分數(shù)據(jù)分成左右兩部分,同樣在左邊放置較小值,右邊放置較大值。右側的數(shù)組數(shù)據(jù)也可以做類似處理。
重復上述過程,可以看出,這是一個遞歸定義。通過遞歸將左側部分排好序后,再遞歸排好右側部分的順序。當左、右兩個部分各數(shù)據(jù)排序完成后,整個數(shù)組的排序也就完成了。
總結來說:就是分治+填數(shù)
以12、10、8、22、5、13、28、21、11我們要將它按從小到大排序排序過程:
詳細過程:
設定兩個指針 left 和 right,它們初始分別指向待排序序列的左端和右端;此外還要附設一個基準元素 tmp(一般選取第一個,本例中基準tmp的值為 20)。
首先從 right 所指的位置從右向左搜索找到第一個小于 tmp 的元素,然后將其記錄在基準元素所在的位置。
接著從 left 所指的位置從左向右搜索找到第一個大于 tmp的元素,然后將其記錄在 right 所指向的位置。
然后再從 right 所指向的位置繼續(xù)從右向左搜索找到第一個小于 tmp 的元素,然后將其記錄在 left 所指向的位置。
接著,left 繼續(xù)從左向右搜索第一個大于 tmp的元素,如果在搜索過程中出現(xiàn)了 left == right ,則說明一趟快速排序結束。此時將 tmp 記錄在 left 和 right 共同指向的位置即可。
以上便是一輪快速排序的詳細過程
注意:
向下劃分至少需要這個組兩個數(shù)據(jù),才有必要劃分,0個或者1個都沒有必要
劃分時:從右向左找比基準小的(相等)
從左向右找比基準值大的
//一次劃分函數(shù) 核心函數(shù) //返回基準值最終所在下標 int Partition(int *arr, int left, int right) { //先講arr數(shù)組里的[left, right]的第一個值 作為基準值 int tmp = arr[left]; while(left < right) { while(left<right && arr[right] > tmp)//左右邊界沒有相遇且當前右邊的值大于基準值tmp right--; if(left < right)//如果此時,左右邊界沒有相遇,那就只能證明右邊right找到了一個小于等于基準值tmp的值 { arr[left] = arr[right]; } else { break; } while(left<right && arr[left] <= tmp)//左右邊界沒有相遇且當前左邊的值小于等于基準值tmp left++; if(left < right)//如果此時,左右邊界沒有相遇,那就只能證明左邊left找到了一個大于基準值tmp的值 { arr[right] = arr[left]; } else { break; } } arr[left] = tmp;//此時 因為 left == right return left;//return right ok } void Quick(int *arr, int left, int right) { if(left < right)//通過left <right 保證[left, right]這個范圍內(nèi)至少兩個數(shù)據(jù) { int par = Partition(arr, left, right); if(left < par-1)//基準值左半部分 至少有兩個值才有必要去遞歸 { Quick(arr, left, par-1); } if(par+1 < right)//基準值右半部分 至少有兩個值才有必要去遞歸 { Quick(arr, par+1, right); } } } void QuickSort(int *arr, int len) { Quick(arr, 0, len-1); }
越亂越快,越有序越慢
時間復雜度:
最優(yōu)情況:O(nlogn)每次數(shù)據(jù)元素都能平均的分成兩個部分。得到一個完全二叉樹;
最壞情況: O(n^2)這個數(shù)僅有右子樹或左子樹,比較次數(shù)為 (n-1)+(n-2) + (n-3) + … +1=n*(n-1)/2 ;
平均情況:O(nlogn)。
空間復雜度:O(1)。
穩(wěn)定性:因為關鍵字的比較和交換是跳躍進行的,會改變數(shù)據(jù)元素的相對位置;因此,快速排序是一種不穩(wěn)定的排序方法,但是也是內(nèi)排序中平均效率最高的排序算法。
以上就是“C語言快速排序如何應用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業(yè)資訊頻道。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。