《大話資料結構》第9章 排序 9.7 堆排序(上)_大話資料結構
來源:互聯網
上載者:User
9.7.1 堆結構介紹 我們前面講到 簡單選擇排序,它在待排序的n個記錄中選擇一個最小的記錄需要比較n-1次。本來這也可以理解,尋找第一個資料需要比較這麼多次正常的,否則如何知道它是最小的記錄。
可惜的是,這樣的操作並沒有把每一趟的比較結果儲存下來,在後一趟的比較中,有許多比較在前一趟已經做過了,但由於前一趟排序時未儲存這些比較結果,所以後一趟排序時又重複執行了這些比較操作,因而記錄的比較次數較多。
如果可以做到每次在選擇到最小的記錄的同時,並根據比較對其他記錄做出相應的調整,那樣排序的總體效率就會非常高了。而堆排序(Heap Sort),就是對簡單選擇排序進行的一種改進,這種改進的效果是非常明顯的。堆排序演算法是Floyd和Williams在1964年共同發明的,同時,他們發明了堆這樣的資料結構。
回憶一下我們小時候,特別是男同學,基本都玩過疊羅漢的惡作劇。通常都是先把某個要整的人按倒在地,然後大家就一擁而上撲了上去……後果。後果當然就是一笑了知,一個惡作劇而已。不過在西班牙的加泰羅尼亞地區,他們將疊羅漢視為了正兒八經的民族體育活動,如圖9-7-1,可以想像當時場面的壯觀。
疊羅漢運動是把人堆在一起,而我們這裡要介紹的“堆”結構相當於把數字記號堆成一個塔型的結構。當然,這絕不是簡單的堆砌。大家看圖9-7-2,能夠找到什麼規律嗎。
很明顯,我們可以發現它們都是二叉樹,如果觀察仔細些,還能看出它們都是完全二叉樹。左圖中根結點是所有元素中最大的,右圖的根結點是所有元素中最小的。再細看看,發現左圖每個結點都比它的左右孩子要大,右圖每個結點都比它的左右孩子要小。這就是我們要講的堆結構。
堆是具有下列性質的完全二叉樹:每個結點的值都大於或等於其左右孩子結點的值,稱為大頂堆(例如圖9-7-2左圖);或者每個結點的值都小於或等於其左右孩子結點的值,稱為小頂堆(例如圖9-7-2右圖)。
這裡需要注意從堆的定義可知,根結點一定是堆中所有結點最大(小)者。較大(小)的結點靠近根結點(但也不絕對,比如右圖小頂堆中60、40均小於70,但它們並沒有70靠近根結點)
如果按照層序遍曆的方式給結點從1開始編號,則結點之間滿足如下關係:
這裡為什麼i要小於等於⌊n/2⌋呢。相信大家可能都忘記了二叉樹的性質5(詳見本書6.6節),其實忘記也不奇怪,這個性質在我們講完之後,就再也沒有提到過它。可以說,這個性質彷彿就是在為堆準備的。性質5的第一條就說一棵完全二叉樹,如果i=1,則結點i是二叉樹的根,無雙親;如果i>1,則其雙親是結點⌊i/2⌋。那麼對於有n個結點的二叉樹而言,它的i值自然就是小於等於⌊n/2⌋了。性質5的第二、三條,也是在說明下標i與2i和2i+1的雙親子女關係。如果完全忘記的同學不妨去複習一下。
如果將圖9-7-2的大頂堆和小頂堆用層序遍曆存入數組,則一定滿足上面的關係表達。如圖9-7-3。
我們現在講這個堆結構,其目的就是為了堆排序用的。 出處:http://www.cnblogs.com/cj723/archive/2011/04/21/2024261.html