美文网首页
树形选择排序-锦标赛排序

树形选择排序-锦标赛排序

作者: bocsoft | 来源:发表于2019-02-25 16:41 被阅读0次
package main

import (
    "fmt"
    "math"
)

//树形选择排序
//声明一个节点的结构体,包含节点数值大小和是否需要参与比较
type node struct {
    value     int  //数值大小
    available bool //叶子节点状态
    rank      int  //叶子中的排序,方便失效
}

func main() {
    var length = 10
    var mm = make(map[int]int, length)
    var o []int

    //先准备一个顺序随机的切片
    for i := 0; i < length; i++ {
        mm[i] = i
    }
    for k, _ := range mm {
        o = append(o, k)
    }

    fmt.Println(o)
    treeSelectionSort(o)
}

func treeSelectionSort(origin []int) []int {
    //树的层数
    var level int
    var result = make([]int, 0, len(origin))
    //计算树的层数
    for pow(2, level) < len(origin) {
        level++
    }
    //叶子节点数
    var leaf = pow(2, level)
    var tree = make([]node, leaf*2-1)

    //先填充叶子节点的数据
    for i := 0; i < len(origin); i++ {
        tree[leaf+i-1] = node{origin[i], true, i}
    }
    //每层都比较叶子兄弟大小,选出较小者作为父节点
    for i := 0; i < level; i++ {
        //当前层节点数
        nodeCount := pow(2, level-i)
        //每组兄弟间比较
        for j := 0; j < nodeCount/2; j++ {
            compareAndUp(&tree, nodeCount-1+j*2) //左节点都是奇数
        }

    }

    //这个时候树顶端的就是最小的元素了
    result = append(result, tree[0].value)
    fmt.Println(result)

    //选出最小元素后,还剩n-1个需要排序
    for t := 0; t < len(origin)-1; t++ {
        //赢球的节点
        winNode := tree[0].rank + leaf - 1
        //把赢球额叶子节点状态更改为失效
        tree[winNode].available = false

        // 从下一轮开始,只需要与每次胜出节点的兄弟节点进行比较
        for i := 0; i < level; i++ {
            leftNode := winNode
            if winNode%2 == 0 {
                leftNode = winNode - 1  //兄弟节点
            }

            //比较兄弟节点大小,并将胜出的节点向上传递
            compareAndUp(&tree, leftNode)
            winNode = (leftNode - 1) / 2
        }

        //每轮都会把最小的推到树顶
        result = append(result, tree[0].value)
        fmt.Println(result)
    }
    return result
}

func pow(x, y int) int {
    return int(math.Pow(float64(x), float64(y)))
}

func compareAndUp(tree *[]node, leftNode int) {
    rightNode := leftNode + 1

    //除非左节点无效或者右节点有效并且比左节点大,否则就无脑选左节点
    if !(*tree)[leftNode].available || ((*tree)[rightNode].available && (*tree)[leftNode].value > (*tree)[rightNode].value) {
        (*tree)[(leftNode-1)/2] = (*tree)[rightNode]
    } else {
        (*tree)[(leftNode-1)/2] = (*tree)[leftNode]
    }
}

//输出结果:
[4 6 8 9 5 7 0 1 2 3]
[0]
[0 1]
[0 1 2]
[0 1 2 3]
[0 1 2 3 4]
[0 1 2 3 4 5]
[0 1 2 3 4 5 6]
[0 1 2 3 4 5 6 7]
[0 1 2 3 4 5 6 7 8]
[0 1 2 3 4 5 6 7 8 9]




相关文章

  • 2018-09-19 树形选择排序

    一,树形选择排序思想 树形选择排序是模拟锦标赛而发明的一种排序方法,又可以称为锦标赛排序。下边以一个具体例子来说明...

  • 树形选择排序-锦标赛排序

  • 06.选择类排序法(树形选择排序,堆排序)

    06.选择类排序法(树形选择排序,堆排序) 参考网页:https://mparticle.uc.cn/articl...

  • iOS - 堆排序

    Demo_github 堆排序 堆排序(Heap Sort)是一种树形选择排序,是对直接选择排序的有效改进。 堆的...

  • 选择排序之堆排序

    堆排序是简单选择排序的一种 是一种树形选择排序方法 排序特点、排序思想:在排序过程中,将L[1...n]视为一棵【...

  • 堆排序(二叉树)

    (1)基本思想:堆排序是一种树形选择排序,是对直接选择排序的有效改进。 堆的定义如下:具有n个元素的序列(h1,h...

  • 2018-04-19 堆排序java

    上一遍中,学习了树形选择排序,https://www.jianshu.com/p/b20ed599ac07树形选择...

  • 选择排序:堆排序(Heap Sort)

    堆排序是一种树形选择排序,是对直接选择排序的有效改进。 基本思想: 堆顶元素(即第一个元素)必为最小项(小顶堆)或...

  • 排序算法(1):堆排序

    图解堆排序 摘要: 堆排序是一种树形选择排序,在排序过程中可以把元素看成是一颗完全二叉树,每个节点都大(小)于它的...

  • 常见排序算法

    这里介绍四种排序算法,选择排序、快速排序、归并排序、计数排序 选择排序(使用递归) 选择排序(使用循环) 快速排序...

网友评论

      本文标题:树形选择排序-锦标赛排序

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