排序總結 快排 歸併 堆排

2021-10-12 12:51:45 字數 2751 閱讀 9509

1.煞筆快排

假設我們對陣列進行快速排序。

首先在這個序列中找乙個數作為基準數,為了方便可以取第乙個數。

遍歷陣列,將小於基準數的放置於基準數左邊,大於基準數的放置於基準數右邊。

此時得到類似於這種排序的陣列。

在初始狀態下7是第乙個位置,現在需要把7挪到中間的某個位置k,也即k位置是兩邊數的分界點。

那如何做到把小於和大於基準數7的值分別放置於兩邊呢,我們採用雙指標法,從陣列的兩端分別進行比對。

先從最右位置往左開始找直到找到乙個小於基準數的值,記錄下該值的位置(記作 i)。

再從最左位置往右找直到找到乙個大於基準數的值,記錄下該值的位置(記作 j)。

如果位置i如果執行到i==j,表示本次比對已經結束,將最後i的位置的值與基準數做交換,此時基準數就找到了臨界點的位置k,位置k兩邊的陣列都比當前位置k上的基準值或都更小或都更大。

上一次的基準值7已經把陣列分為了兩半,基準值7算是已歸位(找到排序後的位置)。

通過相同的排序思想,分別對7兩邊的陣列進行快速排序,左邊對[left, k-1]子陣列排序,右邊則是[k+1, right]子陣列排序。

利用遞迴演算法,對分治後的子陣列進行排序。

static

void

sort

(int

nums,

int start,

int end)

swap

(nums, start, i)

;for

(int num : nums)

system

.out.

print

(num +

", ");

system

.out.

println()

;sort

(nums, start, i -1)

;sort

(nums, i +

1, end);}

static

void

swap

(int

nums,

int i,

int j)

static

void

mergesort

(int

nums,

int start,

int end)

static

void

merge

(int

nums,

int start,

int mid,

int end)

while

(i <= mid) copy[tail++

]= nums[i++];

while

(j <= end) copy[tail++

]= nums[j++];

for(

int k =

0; k < tail;

++k) nums[start + k]

= copy[k]

;}

參考:這裡

堆是一棵順序儲存的完全二叉樹。

其中每個結點的關鍵字都不大於其孩子結點的關鍵字,這樣的堆稱為小根堆。

其中每個結點的關鍵字都不小於其孩子結點的關鍵字,這樣的堆稱為大根堆。

舉例來說,對於n個元素的序列當且僅當滿足下列關係之一時,稱之為堆:

(1) ri <= r2i+1 且 ri <= r2i+2 (小根堆)

(2) ri >= r2i+1 且 ri >= r2i+2 (大根堆)

其中i=1,2,…,n/2向下取整;

首先,按堆的定義將陣列r[0…n]調整為堆(這個過程稱為建立初始堆),交換r[0]和r[n];

然後,將r[0…n-1]調整為堆,交換r[0]和r[n-1];

如此反覆,直到交換了r[0]和r[1]為止。

以上思想可歸納為兩個操作:

(1)根據初始陣列去構造初始堆(構建乙個完全二叉樹,保證所有的父結點都比它的孩子結點數值大)。

(2)每次交換第乙個和最後乙個元素,輸出最後乙個元素(最大值),然後把剩下元素重新調整為大根堆。

當輸出完最後乙個元素後,這個陣列已經是按照從小到大的順序排列了。

堆排序是一種不穩定的排序方法。

因為在堆的調整過程中,關鍵字進行比較和交換所走的是該結點到葉子結點的一條路徑,

因此對於相同的關鍵字就可能出現排在後面的關鍵字被交換到前面來的情況。

// 調整start為根節點的子樹

static

void

adjectheap

(int

nums,

int start,

int length)

if(tmp < nums[child]

)else

} nums[start]

= tmp;

//在調整結束後,把父節點原來值,賦給路徑上的最大孩子

}static

void

heapsort

(int

nums)

// // 進行n-1次迴圈,完成排序,依次將堆頂元素和堆尾互換,調整堆

快排 歸併 堆排

快排 include include include includeusing namespace std void quicksort vector a,int l,int r 終止遞迴的條件,子串行長度為1 int mid low high low 2 取得序列中間的元素 mergesort a...

一些排序方法(堆排,歸併,快排,計數排)

感覺學校演算法課挺水的,不過程式設計這東西還是要靠自己想,自己琢磨,老師也只能幫你指引下。菜鳥我還是好好敲 吧。計數排序 其他排序方法都是依靠元素之間的比較從而產生次序,而計數排序是依靠元素計算,得出自己在序列中的位置 計數排序 設元素均為非負整數 include include using nam...

對歸併 堆排 快排的一些總結。

這三個演算法的理論時間複雜度都是nlogn,但是區別還是很大的。這三個演算法裡,實際效率最低的是堆排序,因為在每次調整大根堆的時候,都把底層元素交換到了根,然後再調整,而底層元素又不可能大於原根元素的兩個孩子節點,因此非等概率調整,做了很多次無效交換,因此實際效率最低。歸併排序時間效率最高,並且穩定...