排序演算法C 實現之推排序詳解

2021-10-07 18:54:26 字數 1748 閱讀 8862

將一組無序陣列變為有序

首先,要對二叉樹有個基本的了解。

在大頂堆中,我們可以輕易獲得最大值。在小頂堆中,我們可以輕易獲得最小值。以大頂堆為例,我們將獲得的最大值max拿出來,將它和陣列arr的末尾元素x交換,這樣我們將陣列中的最大值放在陣列的末尾了(即我們從小到大,公升序排序)。這就和選擇排序一樣,選擇最值來依次排序。

在選擇排序中,我們是靠剩餘元素的比較來獲取最值的。在推排序中,我們靠大頂堆來獲取最值(大頂堆的第乙個元素就是當前最大值)。而現在將max和x交換後,剩餘的元素不滿足大頂堆成立的條件了。我們需要將剩餘的元素轉換成大頂推的形式。同樣的,對於任意給定的無序陣列,其也不是大頂堆的形式,我們也需要將其轉換成大頂推,這樣才能獲取第乙個最值(即整個陣列的最大值)。

簡單來說,就是比較當前元素cur與它的左孩子left和右孩子right的大小。在大頂堆中,找出left和right的最大值與cur比較,如果cur比最大值小,那麼交換兩者。

在陣列arr中,當前元素的位置為i時,看那個大頂堆的圖,可以輕易算出,left的位置為2*i+1,right的位置為2*i+2。

上面只是使得當前元素(即乙個節點)滿足了大頂堆的成立條件,只有所有節點都滿足這個條件,那麼才能構成大頂堆。所以cur的left也要按照上述方式進行比較。

我們知道了left的位置2*i+1=k,那麼其left的left的位置為2*k+1。如此可繼續得到left的left的left的位置,但注意不能超過陣列的最大位置。

這樣,我們又計算了部分節點,但我們計算的節點相當於圖中的0、1、3、7節點,不是所有節點。怎麼樣可以計算到所有節點呢?

按照3 2 1 0的順序計算即可算到所有節點,而3=9/2-1,即整個陣列長度的一半減去一(注意是整數運算)

。(為什麼是這樣?這正是完全二叉樹中序遍歷的性質。)

這樣我們就計算了所有節點,將乙個無序陣列構成大頂堆。再這個大頂堆的最大值和陣列末尾元素交換時,末尾元素變成了標號為0的節點,而其他的節點仍滿足大頂堆的條件,這時,我們只需要對這個點,用比較的方式使其符合大頂推的條件即可。

不斷將陣列的無序部分構成堆來獲取最值,從而使得有序部分元素個數增加,直到陣列完全有序。

using system;

using system.collections;

using system.collections.generic;

using system.linq;

namespace sort

program ps = new program();

ps.heapsort(a);

console.writeline("排序結果:");

foreach (int a in a)

bool issorted = true;

for (int i = 0; i < a.length - 1; i++)

console.write(issorted);

console.readkey();

}public void heapsort(int a)

for (int j = n-1; j >0; j--)

}public void adjustheap(int a,int i,int n)

if (a[k] > temp)//如果當前節點小,則與left和right大的一方交換

else

}a[i] = temp;}}

}

排序演算法C 實現之氣泡排序詳解

假設現在我們有一組資料a 將資料組中的資料元素從小到大排列 即順序,反之逆序 使得資料組由無序變為有序。第一步 按照從左到右的順序獲取資料元素。注意 從左到右 是我們在視覺上看這組資料的描述,在記憶體中或者說在寫 時,我們是按照資料元素的索引從小到大獲取元素的。第二步 比較獲取的第乙個元素與第二個元...

排序演算法C 實現之選擇排序詳解

將無序陣列變為有序陣列 通過迴圈,每次選出在當前的剩餘元素中最小的元素,使得這些選出的元素構成有序陣列 using system namespace selectionsort program ps new program ps.selectsort a console.writeline 排序結果...

排序演算法C 實現之快速排序詳解

將一組大規模無序陣列變為有序 在陣列中隨機選擇乙個數作為基準數temp,在陣列中從後往前找乙個比temp小的數lo,交換lo和temp 在陣列中從前往後找乙個比temp大的數hi,交換temp和hi 重複2 3找lo和hi,直到找不到這樣的數lo,hi。此時temp左邊的數都 它,右邊的數都 它。此...