数据结构之二叉树的层次遍历

从上到下按层打印二叉树,同一层结点按从左到右的顺序打印,每一层打印到一行
输入:
在这里插入图片描述
输出:[[3], [9, 8], [6, 7]]

package main

import "fmt"

// tree
type NodeTree struct {
	Data      int
	LeftNode  *NodeTree
	RightNode *NodeTree
}

type Queue struct {
	Node  []*NodeTree
	QSize int
}

func main() {
	node := CreateTree()
	if node == nil {
		return
	}
	q := &Queue{}
	// 把首节点加入到队列中
	q.Node = append(q.Node, node)
	// 当前层元素个数
	q.QSize = 1
	// 记录当前层元素总个数
	sum := 0
	// 当前层元素data值
	curLevel := make([]int, 0)
	// 结果集
	ret := make([][]int, 0)
	for {
		// 记录当前节点子元素个数
		i := 0
		// 1.遍历当前节点的子节点
		// 从队列中pop出当前子节点
		nodeTemp := q.Pop()
		curLevel = append(curLevel, nodeTemp.Data)
		q.QSize--
		// 把当前节点的左子节点放入队列中
		if nodeTemp.LeftNode != nil {
			q.Push(nodeTemp.LeftNode)
			i++
		}

		// 把当前节点的右子节点放入队列中
		if nodeTemp.RightNode != nil {
			q.Push(nodeTemp.RightNode)
			i++
		}
		sum += i

		//  q.QSize == 0 说明当前层遍历完成
		if q.QSize == 0 {
			// 当前层循环完成,把当前层数据加入到结果集中,当前层置空
			ret = append(ret, curLevel)
			curLevel = nil
			// 当前层所有节点的子节点
			q.QSize = sum
			// 如果子节点个数为0表示已经遍历完成
			if sum == 0 {
				break
			}
			sum = 0
		}
	}
	fmt.Println(ret)
}

// create tree
func CreateTree() *NodeTree {
	node3 := &NodeTree{Data: 3}
	node9 := &NodeTree{Data: 9}
	node8 := &NodeTree{Data: 8}
	node6 := &NodeTree{Data: 6}
	node7 := &NodeTree{Data: 7}
	// node4 := &NodeTree{Data: 4}
	// node2 := &NodeTree{Data: 2}
	node3.LeftNode = node9
	node9.LeftNode = nil
	node9.RightNode = nil
	node3.RightNode = node8
	node8.LeftNode = node6
	node8.RightNode = node7
	node6.LeftNode = nil
	node6.RightNode = nil
	node7.LeftNode = nil
	node7.RightNode = nil
	// node4.LeftNode = nil
	// node4.RightNode = nil
	// node2.LeftNode = nil
	// node2.RightNode = nil
	return node3
}

// POP queue
func (q *Queue) Pop() *NodeTree {
	if len(q.Node) > 0 {
		ret := q.Node[0]
		q.Node = q.Node[1:]
		return ret
	}
	return nil
}

// PUSH queue
func (q *Queue) Push(node *NodeTree) {
	s := append(q.Node, node)
	q.Node = s
}


第二种:

func main() {
	// 	Step 1. 首先将结点 3 加入 cur,,形成 cur=[3]。
	// Step 2. 开始依次遍历当前层 cur, 这里 cur 只有结点 3,依次把结点 3 的左子结点和右子结点加入 next,形成 [9, 8]。
	// Step 3. 将 cur 指向 next,并且 next 设置为 []
	// Step 4. 依次遍历 cur,并将每个结点的左右子结点放到 next 中。
	// Step 5. 将 cur 指向 next。并依次遍历。由于这是最后一层,所以不会再生成 next。
	// Step 6. 最后得到层次遍历的结果。
	// m1() 第一种解法
	node := CreateTree()
	if node == nil {
		return
	}
	cur := []NodeTree{}
	cur = append(cur, *node)
	ret := make([][]int, 0)
	for len(cur) > 0 {
		// 下一层
		next := []NodeTree{}
		// 当前层数据
		curLevel := make([]int, 0)
		// 循环当前层所有节点,并且将子节点添加到下一层中
		for _, item := range cur {
			curLevel = append(curLevel, item.Data)
			if item.LeftNode != nil {
				next = append(next, *item.LeftNode)
			}
			if item.RightNode != nil {
				next = append(next, *item.RightNode)
			}
		}
		// 把下一层给当前层
		cur = next
		if len(curLevel) > 0 {
			ret = append(ret, curLevel)
		}
	}
	fmt.Println(ret)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值