Algorithm 戈朗堆和堆

Algorithm 戈朗堆和堆,algorithm,data-structures,go,heap,max-heap,Algorithm,Data Structures,Go,Heap,Max Heap,因此,我正在尝试实现一个max-heap进行练习,以便熟悉Go type MaxHeap struct { slice []int heapSize int } func BuildMaxHeap(slice []int) MaxHeap{ h := MaxHeap{slice: slice, heapSize: len(slice)} for i := len(slice)/2; i >= 0; i-- { h.MaxHeapify(i)

因此,我正在尝试实现一个max-heap进行练习,以便熟悉Go

type MaxHeap struct {
    slice []int
    heapSize int
}
func BuildMaxHeap(slice []int) MaxHeap{
    h := MaxHeap{slice: slice, heapSize: len(slice)}
    for i := len(slice)/2; i >= 0; i-- {
        h.MaxHeapify(i)
    }
    return h
}

func (h MaxHeap) MaxHeapify(i int) {
    left := 2*i
    right := 2*i + 1
    largest := i
    slice := h.slice

    if left < h.size() {
        if slice[left] > slice[i] {
            largest = left
        } else {
            largest = i
        }
    }
    if right < h.size() {
        if slice[right] > slice[largest] {
            largest = right
        }
    }
    if largest != i {
        prevLargest := slice[i]
        slice[i] = slice[largest]
        slice[largest] = prevLargest
        h.MaxHeapify(largest)
    }
}

它不起作用。

问题是切片索引从零开始,因此:

left := 2*i
right := 2*i + 1
给出索引0的左子级0,即索引本身。 只需在每一个上面加一个

您的heapSort在调用h.MaxHeapify1而不是0时遇到类似问题。这实际上留下了前面的任何价值

这里是代码的一个修改版本,它可以正常工作。测试文件也包括在内,它使用testing/quick根据容器/堆和排序对代码进行验证

heap.go:
问题是切片索引从零开始,因此:

left := 2*i
right := 2*i + 1
给出索引0的左子级0,即索引本身。 只需在每一个上面加一个

您的heapSort在调用h.MaxHeapify1而不是0时遇到类似问题。这实际上留下了前面的任何价值

这里是代码的一个修改版本,它可以正常工作。测试文件也包括在内,它使用testing/quick根据容器/堆和排序对代码进行验证

heap.go:
这里有一种方法可以做同样的事情,而无需添加用于保存数据和进行堆化的结构:

// AS described in Introduction to Algorithms (3rd Edition)
package main

import (
    "fmt"
)

func left(i int) int {
    return 2 * i
}

func right(i int) int {
    return 2*i + 1
}

func parent(i int) int {
    return i / 2
}

func maxHeapify(a []int, i int) []int {

    fmt.Printf("Array: %v\n", a)

    l := left(i) + 1
    r := right(i) + 1
    var largest int
    if l < len(a) && l >= 0 && a[l] > a[i] {
        largest = l
    } else {
        largest = i
    }
    if r < len(a) && r >= 0 && a[r] > a[largest] {
        largest = r
    }
    if largest != i {
        fmt.Printf("Exchanging: %d index (%d) with %d index (%d)\n", a[i], i, a[largest], largest)
        a[i], a[largest] = a[largest], a[i]
        a = maxHeapify(a, largest)
    }
    return a
}

func buildMaxHeap(a []int) []int {
    for i := len(a)/2 - 1; i >= 0; i-- {
        fmt.Printf("Building: %d index %d\n", a[i], i)
        a = maxHeapify(a, i)
    }
    return a
}

func heapsort(a []int) []int {

    a = buildMaxHeap(a)
    fmt.Printf("Starting sort ... array is %v\n", a)
    size := len(a)
    for i := size - 1; i >= 1; i-- {
        a[0], a[i] = a[i], a[0]
        size--
        maxHeapify(a[:size], 0)
    }
    return a
}

func main() {

    a := [10]int{4, 1, 3, 2, 16, 9, 10, 14, 8, 7}
    fmt.Printf("Array: %v\n", a)

    b := heapsort(a[:])
    fmt.Printf("Array: %v\n", b)

}

这里有一种方法可以做同样的事情,而无需添加用于保存数据和进行堆化的结构:

// AS described in Introduction to Algorithms (3rd Edition)
package main

import (
    "fmt"
)

func left(i int) int {
    return 2 * i
}

func right(i int) int {
    return 2*i + 1
}

func parent(i int) int {
    return i / 2
}

func maxHeapify(a []int, i int) []int {

    fmt.Printf("Array: %v\n", a)

    l := left(i) + 1
    r := right(i) + 1
    var largest int
    if l < len(a) && l >= 0 && a[l] > a[i] {
        largest = l
    } else {
        largest = i
    }
    if r < len(a) && r >= 0 && a[r] > a[largest] {
        largest = r
    }
    if largest != i {
        fmt.Printf("Exchanging: %d index (%d) with %d index (%d)\n", a[i], i, a[largest], largest)
        a[i], a[largest] = a[largest], a[i]
        a = maxHeapify(a, largest)
    }
    return a
}

func buildMaxHeap(a []int) []int {
    for i := len(a)/2 - 1; i >= 0; i-- {
        fmt.Printf("Building: %d index %d\n", a[i], i)
        a = maxHeapify(a, i)
    }
    return a
}

func heapsort(a []int) []int {

    a = buildMaxHeap(a)
    fmt.Printf("Starting sort ... array is %v\n", a)
    size := len(a)
    for i := size - 1; i >= 1; i-- {
        a[0], a[i] = a[i], a[0]
        size--
        maxHeapify(a[:size], 0)
    }
    return a
}

func main() {

    a := [10]int{4, 1, 3, 2, 16, 9, 10, 14, 8, 7}
    fmt.Printf("Array: %v\n", a)

    b := heapsort(a[:])
    fmt.Printf("Array: %v\n", b)

}

您可能应该包括MaxHeap类型定义。顺便说一句,您看过吗?特别是,你可以将你的实现与他们对源代码的点击操作进行比较。是的,但我试图以Cormen's algorithms Book中的方式实现它。另外一个顺便说一句,没有解决这个问题,对不起:你可以只做slice[I],slice[magnize]=slice[magnizer],slice[I]交换两个条目。代码的可运行版本:您可能应该包含MaxHeap类型定义。顺便说一句,您看过吗?特别是,你可以将你的实现与他们对源代码的点击操作进行比较。是的,但我试图以Cormen's algorithms Book中的方式实现它。另外一个顺便说一句,没有解决这个问题,对不起:你可以只做slice[I],slice[magnize]=slice[magnizer],slice[I]要交换两个条目,请执行代码的可运行版本:
// AS described in Introduction to Algorithms (3rd Edition)
package main

import (
    "fmt"
)

func left(i int) int {
    return 2 * i
}

func right(i int) int {
    return 2*i + 1
}

func parent(i int) int {
    return i / 2
}

func maxHeapify(a []int, i int) []int {

    fmt.Printf("Array: %v\n", a)

    l := left(i) + 1
    r := right(i) + 1
    var largest int
    if l < len(a) && l >= 0 && a[l] > a[i] {
        largest = l
    } else {
        largest = i
    }
    if r < len(a) && r >= 0 && a[r] > a[largest] {
        largest = r
    }
    if largest != i {
        fmt.Printf("Exchanging: %d index (%d) with %d index (%d)\n", a[i], i, a[largest], largest)
        a[i], a[largest] = a[largest], a[i]
        a = maxHeapify(a, largest)
    }
    return a
}

func buildMaxHeap(a []int) []int {
    for i := len(a)/2 - 1; i >= 0; i-- {
        fmt.Printf("Building: %d index %d\n", a[i], i)
        a = maxHeapify(a, i)
    }
    return a
}

func heapsort(a []int) []int {

    a = buildMaxHeap(a)
    fmt.Printf("Starting sort ... array is %v\n", a)
    size := len(a)
    for i := size - 1; i >= 1; i-- {
        a[0], a[i] = a[i], a[0]
        size--
        maxHeapify(a[:size], 0)
    }
    return a
}

func main() {

    a := [10]int{4, 1, 3, 2, 16, 9, 10, 14, 8, 7}
    fmt.Printf("Array: %v\n", a)

    b := heapsort(a[:])
    fmt.Printf("Array: %v\n", b)

}