满二叉树可以使用数组进行表示和遍历
给定高度后,二叉树共有 2^n - 1 个节点
生成 2^n - 1 个节点的数组后,第i个(i从0开始)节点的左孩子为 i = 2i+1,第 i 个节点的右孩子为 i = 2i+2。
根据此此规律可以不用生成树状结构,直接使用数组进行遍历。
例题:
有一颗二叉树, 最大深度为 D(1 <= D <= 26), 且所有叶子的深度都相同. 所有的节点从上到下从左到右编号为1, 2, 3, … , 2^D - 1. D 的意思是二叉树的高度, 比如当 D = 1 时, 二叉树只有一个节点, 当 D = 2 时, 二叉树有两层, 节点为1, 2, 3, 当 D = 3 时, 节点为 1, 2, 3, 4, 5, 6, 7. 以此类推. 在节点 1 处放一个小球, 它会往下落. 每个内节点上都有一个开关, 初始全部关闭, 当每次有小球落到一个开关上时, 它的状态都会改变. 当小球到达一个内节点时, 如果该节点上的开关关闭, 则往左走, 否则往右走, 直到走到叶子节点.
输入包括两个数, 树的深度D和小球的个数I(1 <= N <= 500000), 并用空格隔开.
输出包括一个数字, 第 N 个小球最后所在的叶子节点的编号.
输入:
4 2
3 4
10 1
2 2
8 128
16 12345
输出:
12
7
512
3
255
36358
package main
import (
"fmt"
"math"
)
type treeNode struct {
// light opened -> 1
// light closed -> 0
val int
left *treeNode
right *treeNode
}
func main() {
for {
var height, ballNum int
fmt.Scan(&height, &ballNum)
if height == 0 && ballNum == 0 {
return
}
nodes := generateTree(height)
endNode := 0
for i := 0; i < ballNum; i++ {
traverseTree(nodes, 0, &endNode)
}
fmt.Println(endNode + 1)
}
}
func generateTree(height int) []int {
totalNodes := int(math.Pow(2, float64(height)) - 1)
var nodes []int
for i := 1; i <= totalNodes; i++ {
nodes = append(nodes, 0)
}
return nodes
}
func traverseTree(arr []int, i int, endNode *int) {
if i < len(arr) {
if arr[i] == 0 {
arr[i] = 1
if 2*i+1 < len(arr) {
traverseTree(arr, 2*i+1, endNode)
} else {
*endNode = i
}
} else {
arr[i] = 0
if 2*i+2 < len(arr) {
traverseTree(arr, 2*i+2, endNode)
} else {
*endNode = i
}
}
}
}
主要是理解二叉树的数组表示
2847

被折叠的 条评论
为什么被折叠?



