堆排序 三角堆的疊加

2021-06-03 07:06:16 字數 1729 閱讀 2310

按自己的理解,可以分成很多個三角堆疊加。那麼堆的調整就是對三角堆的調整:把最大值或最小值交換到三角堆的頂部,再遞迴。

1-堆的基本結構

一、最基本的三角堆調整遞迴函式:

/*************三角堆調整******************/

/*1、調整為三角節點,頂部為最大值

2、遞迴:向關鍵值較大的孩子節點向下進行

*//*

cin:陣列a,需要調整的三角節點頂部:i,陣列總長:size。

*/void heapadjust(int *a,int i,int size) //調整堆 從i-size間的調整

if(rchild<=size&&a[rchild]>a[tmp])

//判定找到孩子節點,則把孩子節點交換到頂部

if(tmp!=i)

}

二、建立堆:多個三角堆疊加起來。

思想:把最大值逐步交換到頂部,建立大頂堆,且每個子節點都是大頂堆***/

1、從下往上逐漸調整三角堆,自底而上地呼叫heapadjust來將乙個陣列a[1..size]變成乙個最大堆

/***從最下面的三角堆開始調整,即非葉子節點的最大序號處開始往上調整***

**cin:陣列a,陣列大小

*/

void buildheap(int *a,int size)    //建立堆 

}

三、堆排序:

/*思想:交換堆頂和最後乙個元素,即每次將剩餘元素中的最大者放到最後面,

1、交換

2、重新調整三角堆

// 堆排序

// 初始呼叫buildmaxheap將a[1..size]變成最大堆

// 因為陣列最大元素在a[1],則可以通過將a[1]與a[size]互換達到正確位置

// 現在新的根元素破壞了最大堆的性質,所以呼叫heapadjust調整,

// 使a[1..size-1]成為最大堆,a[1]又是a[1..size-1]中的最大元素,

// 將a[1]與a[size-1]互換達到正確位置。

// 反覆呼叫heapadjust,使整個數組成從小到大排序。

// 注意: 交換只是破壞了以a[1]為根的二叉樹最大堆性質,它的左右子二叉樹還是具備最大堆性質。

//        這也是為何在buildmaxheap時需要遍歷size/2到1的結點才能構成最大堆(自底往上),而這裡只需要堆化a[1]即可

---swap()交換堆頂和此堆的最後乙個元素

---heapadjust()重新調整函式-三角堆調整*/

void heapsort(int *a,int size) //堆排序

}

3、測試**

int main(int argc, char *argv)

總結:基本操作為三角堆的(從上往下)遞迴調整。(i~size),i為當前三角堆的頂節點。

建堆:從下往上逐步調整三角堆。(size/2,size)。

堆排序:頂部與最末值的交換+三角堆排序

時間複雜度:

在用陣列的實現方式中,每次都把新加入的數值放入陣列的末尾。如果這個數比它現在所在位置的父節點的數值小,那麼就要把他倆交換。如果在新的位置上還是比它的父節點小,就遞迴地繼續這個過程。這個過程和二叉樹的高度成正比,所以是logn。如果把所有n個數都插入進來,那麼最壞情況的時間就是o(n*logn).

選擇排序(三) 堆排序

這樣,還剩下兩個問題 1.如何將乙個交換後的無序區調整為大根堆 2.如何在排序之前建立那個初始的大根堆。而第二個問題是可以通過第乙個問題的解決而解決的。1.如何將乙個交換後的無序區調整為大根堆?由於進行元素交換前,無序區是乙個大根堆,即左子樹和右子樹都是大根堆,所以根節點變化後左右子樹仍然都是大根堆...

排序演算法 三 堆排序

1.heap.class package cn.sort.heap 堆排序實現 公升序排序 author ly public class heap system.out.println 向下調整 先拿左右子樹進行比較,看誰比較大,然後再拿大的與父結點進行比較,若孩子結點比較大,則大孩子與父結點交換,...

選擇排序(三) 堆排序

這樣,還剩下兩個問題 1.如何將乙個交換後的無序區調整為大根堆 2.如何在排序之前建立那個初始的大根堆。而第二個問題是可以通過第乙個問題的解決而解決的。1.如何將乙個交換後的無序區調整為大根堆?由於進行元素交換前,無序區是乙個大根堆,即左子樹和右子樹都是大根堆,所以根節點變化後左右子樹仍然都是大根堆...