美文网首页
算法导论第六章-堆排序(三)&(四)

算法导论第六章-堆排序(三)&(四)

作者: Ahungrynoob | 来源:发表于2018-06-03 22:18 被阅读0次

6.3-1说明BUILD-MAX-HEAP在数组A=[5,3,17,10,84,19,6,22,9]上的操作过程
答:废话不多说,直接上代码,这次在接口上添加了一个BuildMaxHeap函数,基于上一节的MaxHeapify函数,美滋滋。

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)
}

打印出来的结果:[84 22 19 10 3 17 6 5 9]

对于BUILD-MAX-HEAP中第二行的循环控制变量i来说,为什么我们要求它是从[A.length/2]到1递减,而不是从1到[A.length/2]递增呢?
答:因为这样才能保证对于每个子堆的根元素,它的子堆是最大堆。

6.3-3 证明:对于任一包含n个元素的堆中,至多有[n/2^(h+1)]个高度为h的结点
答:利用数学归纳法。当h=0时,有n/2个结点,成立。
当h=k时,假设有[n/2^(k+1)]个高度为k的结点成立。
则当h=k+1时,对于一棵二叉树来说则有[n/2(k+1)]/2个结点,即[n/2(k+2)]个结点,结论成立。

6.4-1 说明HEAPSORT在数组A=[5,13,2,25,7,17,20,8,4]上的操作过程
答:老规矩:直接上代码。

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)
}

结果:[2 4 5 7 8 13 17 20 25]

6.4-3 对于一个按升序排列的包含n个元素的有序数组A来说,HEAPSORT的复杂度是多少?如果A是降序呢?
答:升序情况下:复杂度为nlgn,和最坏情况没有区别。
降序情况下:复杂度为依然为nlgn。

6.4-4 证明在最坏的情况下,HEAPSORT的时间复杂度是nlgn
答:每次调用BUILD-MAX-HEAP的时间复杂度是O(n),而n-1次调用MAX-HEAPIFY,每次的时间复杂度是O(lgn),所以总的来说时间复杂度为nlgn。

相关文章

  • 算法导论第六章-堆排序(三)&(四)

    6.3-1说明BUILD-MAX-HEAP在数组A=[5,3,17,10,84,19,6,22,9]上的操作过程答...

  • 堆排序HeapSort

    引用算法导论中对于堆排序的描述: Like merge sort,but unlike insertion sor...

  • 计数排序、基数排序和桶排序

    阅读经典——《算法导论》07 到目前为止,我们已经介绍了插入排序、归并排序、堆排序、快速排序这四种排序算法,他们的...

  • [算法导论]堆排序

    主要测试大堆,测试源码在(github) 堆 堆可以看成一个近似的完全二叉树,除了底层外,该树是完全充满的,而且是...

  • 堆排序

    阅读经典——《算法导论》05 本文介绍一种神奇的排序方法:堆排序。 堆排序不像插入排序和归并排序那样直观,它利用了...

  • 浅谈排序算法

    前段时间在看计算机科学科学及编程导论,其中谈到了排序的各种算法,在这我浅谈四种插入,选择,冒泡,以及堆排序。 首先...

  • 算法导论第六章-堆排序(一)

    6.1-1 在高度为h的堆中,元素个数最多和最少分别是多少? 答:最多为2^(h+1)-1个元素,最少为2^h个元...

  • 算法导论第六章-堆排序(五)

    6.5-1~6.5-5:略 可以参考最小优先队列的golang实现 6.5-6 在HEAP-INCREASE-KE...

  • 算法导论第六章-堆排序(二)

    6.2-1 直接上MAX-HEAPIFY的go语言实现: 6.2-2 :参考MAX-HEAPIFY,写出能够维护相...

  • iOS算法总结-堆排序

    iOS算法总结-堆排序 iOS算法总结-堆排序

网友评论

      本文标题:算法导论第六章-堆排序(三)&(四)

      本文链接:https://www.haomeiwen.com/subject/gwyssftx.html