• 堆排序之golang实现


    主要是理解思路,思路有了代码则是水到渠成。

    堆排序实际是数组排序,使用数组的下标构造成一个二叉树,想法很有意思。

    加入有数组a,那可以把a[0]视为根节点,它的子节点为a[2*0+1],a[2*0+2],即对于任何一个节点a[i],则有子节点a[2*i+1]和a[2*i+2]。

    1. 构建一个大顶堆,构建成功后a[0]便是最大的。

    2. 之后交换a[0]和a[len(a)-1]

    3. 然后在调整a[:len(a)-2](把a[len(a)-1]排除在外)为大顶堆

    4. 重复上面的步骤

    5. 得到有序数组

    package main
    
    import (
    	"fmt"
    )
    
    func adjustHeap(a []int, pos int, lenght int) {
    	for {
    		// 计算孩子位置
    		child := pos*2 + 1
    		// 检查孩子是否越界
    		if child >= (lenght - 1) {
    			break
    		}
    
    		// 找出孩子中较大的那个
    		if a[child+1] > a[child] {
    			child++
    		}
    		// 检查孩子是否大于父亲,如果大于则交换
    		if a[pos] < a[child] {
    			// 父子交换
    			a[pos], a[child] = a[child], a[pos]
    			// 更新位置,指向子节点
    			pos = child
    		} else {
    			// 如果子节点都小于父节点了,那就可以结束调整了
    			break
    		}
    	}
    }
    
    func buildHeap(a []int) {
    	// 从底层向上层构建,len(a)/2-1是第一个非叶子
    	for i := len(a)/2 - 1; i >= 0; i-- {
    		adjustHeap(a, i, len(a))
    	}
    }
    
    func heapSort(a []int) {
    	// 构建大顶堆
    	buildHeap(a)
    
    	fmt.Println("buildHeap over:", a)
    	fmt.Println("===============================")
    
    	// 首尾交换,重新构建大顶堆
    	for i := len(a) - 1; i >= 0; i-- {
    		a[0], a[i] = a[i], a[0]
    		adjustHeap(a, 0, i)
    	}
    
    }
    
    func main() {
    	num := []int{98, 48, 777, 63, 57, 433, 23, 1112, 1}
    	heapSort(num)
    	fmt.Println("heap sort over:", num)
    }
    

      

  • 相关阅读:
    day10 Java学习(开发工具.Eclipse)
    day9 Java学习(面向对象Package关键字)
    day8 Java学习(面向对象.多态&接口)
    day7 Java学习(面向对象.继承)
    day5 Java学习(面向对象)
    day4 Java学习(数组)
    day3 Java学习(循环结构)
    day2 Java学习(位运算符)
    2019-05-26 java学习日记
    2019-05-25 java学习日记
  • 原文地址:https://www.cnblogs.com/zcqkk/p/9636325.html
Copyright © 2020-2023  润新知