二叉树类高频算法题golang实现

17 篇文章 0 订阅

1、二叉树的先序遍历、中序遍历、后序遍历

先序遍历:根节点-->左子树--->右子树

type TreeNode struct{
    Value int
    Left,Right *TreeNode
}

func (node *TreeNode) traverse(){
	if node ==nil{
		return
	}
	fmt.Print(node.Value+" ")
	node.Left.traverse()
	node.Right.traverse()
}

中序遍历:左子树--->根节点---->右子树

func (node *TreeNode) traverse(){
	if node ==nil{
		return
	}
	node.Left.traverse()
    fmt.Print(node.Value+" ")
	node.Right.traverse()
}

后序遍历:左子树--->右子树--->根节点

func (node *TreeNode) traverse(){
	if node ==nil{
		return
	}
	node.Left.traverse()
	node.Right.traverse()
    fmt.Print(node.Value+" ")
}

3、二叉树的层次遍历

type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}
func levelOrder(root *TreeNode) [][]int {
	if root == nil {
		return nil
	}
	res := [][]int{}
	que := []*TreeNode{root} //队列
	for len(que) > 0 {
		queSize := len(que) //当前层的节点数目
		current := []int{} //存储当前层的节点值
		for i := 0; i < queSize; i++ {
			out := que[0] //取出队列的第一个节点
			que = que[1:] //删除队列的第一个节点
			current = append(current, out.Val) 
			if out.Left != nil {
				que = append(que, out.Left)
			}
			if out.Right != nil {
				que = append(que, out.Right)
			}
		}
		res = append(res, current) //将每层节点值的数组追加到二维数组res
	}
	return res
}

4、二叉树的锯齿形层次遍历

func zigzagLevelOrder(root *TreeNode) (ans [][]int) {
	if root == nil {
		return nil
	}
	res := [][]int{}
	que := []*TreeNode{root} //队列
	for l := 0; len(que) > 0; l++ {
		queSize := len(que) //当前层的节点数目
		current := []int{}  //存储当前层的节点值
		for i := 0; i < queSize; i++ {
			out := que[0] //取出队列的第一个节点
			que = que[1:] //删除队列的第一个节点

			if out.Left != nil {
				que = append(que, out.Left)
			}
			if out.Right != nil {
				que = append(que, out.Right)
			}
			current = append(current, out.Val)
		}
		if l%2 != 0 { //根据l%2是否为零,决定先从左往右,还是先从右往左
			for j := 0; j < len(current)/2; j++ {
				index := len(current) - j - 1
				if j != index {
					current[j], current[index] = current[index], current[j]
				}
			}
		}
		res = append(res, current) //将每层节点值的数组追加到二维数组res
	}
	return res
}

5、二叉树的最大宽度

type TreeNode struct {
	Val   int
	Left  *TreeNode
	Right *TreeNode
}
//标记节点的层数和位置
type AnnotatedNode struct {
	Node         *TreeNode
	Depth, Posit int
}

func newAnnotatedNode(n *TreeNode, d, p int) *AnnotatedNode {
	return &AnnotatedNode{
		Node:  n,
		Depth: d,
		Posit: p,
	}
}

func widthOfBinaryTree(root *TreeNode) (width float64) {
	que := []*AnnotatedNode{newAnnotatedNode(root, 0, 0)}
	var curDepth, left int
	for len(que) > 0 {
		for _, anNode := range que {
			que = que[1:]
			if anNode.Node != nil { 
				que = append(que, newAnnotatedNode(anNode.Node.Left, anNode.Depth+1, anNode.Posit*2))
				que = append(que, newAnnotatedNode(anNode.Node.Right, anNode.Depth+1, anNode.Posit*2+1))
				fmt.Println("Val,curDepth,anode.D,anode.P:", anNode.Node.Val, curDepth, anNode.Depth, anNode.Posit)
				if curDepth != anNode.Depth {
					curDepth = anNode.Depth
					left = anNode.Posit
				}
				width = math.Max(width, float64(anNode.Posit-left+1))
			}
		}
	}
	return
}


func main() {
	//创建一棵树、
	root := new(TreeNode)
	root.Val = 9
	left1 := new(TreeNode)
	left1.Val = 6
	right1 := new(TreeNode)
	right1.Val = 8
	left2 := new(TreeNode)
	left2.Val = 3
	right2 := new(TreeNode)
	right2.Val = 5
	root.Left = left1
	root.Right = right1
	left1.Left = left2
	right1.Right = right2

	levelOrder(root)
	zigzagLevelOrder(root)
    width := widthOfBinaryTree(root)
	fmt.Println("width", width)
}
编译输出:
levelOrder:res  [[9] [6 8] [3 5]]
zigzagLevelOrder:res  [[9] [8 6] [3 5]]  //  l%2 != 0 
zigzagLevelOrder:res  [[9] [6 8] [5 3]]  //  l%2 == 0

Val,curDepth,anode.D,anode.P: 9 0 0 0
Val,curDepth,anode.D,anode.P: 6 0 1 0
Val,curDepth,anode.D,anode.P: 8 1 1 1
Val,curDepth,anode.D,anode.P: 3 1 2 0
Val,curDepth,anode.D,anode.P: 5 2 2 3
Val,curDepth,anode.D,anode.P: 7 2 3 7
width 4

6、比较两个二叉树是否相等

判断两个二叉树相等的条件是:两个二叉树的结构相同,并且相同的节点上具有相同的值。

思路:递归遍历两个树,判断值是否相等


func isSameTree(p, q *TreeNode) bool {
	if p == nil && q == nil {
		return true
	}
	if p == nil || q == nil {
		return false
	}
	if p.Val != q.Val {
		return false
	}
	return isSameTree(p.Left, q.Left) && isSameTree(p.Right, q.Right)
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值