算法導(dǎo)論第六章-堆排序(三)&(四)

6.3-1說明BUILD-MAX-HEAP在數(shù)組A=[5,3,17,10,84,19,6,22,9]上的操作過程
答:廢話不多說,直接上代碼,這次在接口上添加了一個BuildMaxHeap函數(shù),基于上一節(jié)的MaxHeapify函數(shù),美滋滋。

package main

import (
    "fmt"
)

type heapify interface {
    LEFT(i int) int
    RIGHT(i int) int
    MaxHeapify(i int)
    BuildMaxHeap()
}

type maxHeap []int

func (A maxHeap) LEFT(i int) int {
    return i << 1
}

func (A maxHeap) RIGHT(i int) int {
    return (i<<1 + 1)
}

func (A maxHeap) MaxHeapify(i int) {
    largest := i
    l := A.LEFT(i)
    r := A.RIGHT(i)
    if l <= len(A) && A[l-1] > A[i-1] {
        largest = l
    }
    if r <= len(A) && A[r-1] > A[largest-1] {
        largest = r
    }
    if largest != i {
        A[largest-1], A[i-1] = A[i-1], A[largest-1]
        A.MaxHeapify(largest)
    }
}

func (A maxHeap) BuildMaxHeap() {
    for i := len(A) / 2; i > 0; i-- {
        A.MaxHeapify(i)
    }
}

func main() {
    a := maxHeap{5, 3, 17, 10, 84, 19, 6, 22, 9}
    var h heapify = a
    h.BuildMaxHeap()
    fmt.Println(h)
}

打印出來的結(jié)果:[84 22 19 10 3 17 6 5 9]

對于BUILD-MAX-HEAP中第二行的循環(huán)控制變量i來說,為什么我們要求它是從[A.length/2]到1遞減,而不是從1到[A.length/2]遞增呢?
答:因為這樣才能保證對于每個子堆的根元素,它的子堆是最大堆。

6.3-3 證明:對于任一包含n個元素的堆中,至多有[n/2^(h+1)]個高度為h的結(jié)點
答:利用數(shù)學(xué)歸納法。當(dāng)h=0時,有n/2個結(jié)點,成立。
當(dāng)h=k時,假設(shè)有[n/2^(k+1)]個高度為k的結(jié)點成立。
則當(dāng)h=k+1時,對于一棵二叉樹來說則有[n/2(k+1)]/2個結(jié)點,即[n/2(k+2)]個結(jié)點,結(jié)論成立。

6.4-1 說明HEAPSORT在數(shù)組A=[5,13,2,25,7,17,20,8,4]上的操作過程
答:老規(guī)矩:直接上代碼。

package main

import (
    "fmt"
)

type heapify interface {
    LEFT(i int) int
    RIGHT(i int) int
    MaxHeapify(i int, heapSize int)
    BuildMaxHeap()
    HeapSort()
}

type maxHeap []int

func (A maxHeap) LEFT(i int) int {
    return i << 1
}

func (A maxHeap) RIGHT(i int) int {
    return (i<<1 + 1)
}

func (A maxHeap) MaxHeapify(i int, heapSize int) {
    largest := i
    l := A.LEFT(i)
    r := A.RIGHT(i)
    if l <= heapSize && A[l-1] > A[i-1] {
        largest = l
    }
    if r <= heapSize && A[r-1] > A[largest-1] {
        largest = r
    }
    if largest != i {
        A[largest-1], A[i-1] = A[i-1], A[largest-1]
        A.MaxHeapify(largest, heapSize)
    }
}

func (A maxHeap) BuildMaxHeap() {
    for i := len(A) / 2; i > 0; i-- {
        A.MaxHeapify(i, len(A))
    }
}

func (A maxHeap) HeapSort() {
    A.BuildMaxHeap()
    for i := len(A); i >= 1; i-- {
        A[i-1], A[0] = A[0], A[i-1]
        A.MaxHeapify(1, i-1)
    }
}

func main() {
    a := maxHeap{5, 13, 2, 25, 7, 17, 20, 8, 4}
    var h heapify = a
    h.HeapSort()
    fmt.Println(h)
}

結(jié)果:[2 4 5 7 8 13 17 20 25]

6.4-3 對于一個按升序排列的包含n個元素的有序數(shù)組A來說,HEAPSORT的復(fù)雜度是多少?如果A是降序呢?
答:升序情況下:復(fù)雜度為nlgn,和最壞情況沒有區(qū)別。
降序情況下:復(fù)雜度為依然為nlgn。

6.4-4 證明在最壞的情況下,HEAPSORT的時間復(fù)雜度是nlgn
答:每次調(diào)用BUILD-MAX-HEAP的時間復(fù)雜度是O(n),而n-1次調(diào)用MAX-HEAPIFY,每次的時間復(fù)雜度是O(lgn),所以總的來說時間復(fù)雜度為nlgn。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容