树 树有多个节点(node),用以储存元素。某些节点之间存在一定的关系,用连线表示,连线称为边(edge)。边的上端节点称为父节点,下端称为子节点。树像是一个不断分叉的树根
树的深度为层次数
树是元素的集合。
该集合可以为空。这时树中没有元素,我们称树为空树 (empty tree)。
如果该集合不为空,那么该集合有一个根节点,以及0个或者多个子树。根节点与它的子树的根节点用一个边(edge)相连
树的实现: 每个节点储存元素和多个指向子节点的指针。然而,子节点数目是不确定的。一个父节点可能有大量的子节点,而另一个父节点可能只有一个子节点,而树的增删节点操作会让子节点的数目发生进一步的变化。这种不确定性就可能带来大量的内存相关操作,并且容易造成内存的浪费
二叉树与二叉搜索树 二叉树(binary)是一种特殊的树。二叉树的每个节点最多只能有2个子节点
由于二叉树的子节点数目确定,所以可以直接采用上图方式在内存中实现。每个节点有一个左子节点(left children)和右子节点(right children)。左子节点是左子树的根节点,右子节点是右子树的根节点。
如果我们给二叉树加一个额外的条件,就可以得到一种被称作二叉搜索树(binary search tree)的特殊二叉树。二叉搜索树要求:每个节点都不比它左子树的任意元素小,而且不比它的右子树的任意元素大。
二叉搜索树可以方便的实现搜索算法。在搜索元素x的时候,我们可以将x和根节点比较:
如果x等于根节点,那么找到x,停止搜索 (终止条件)
如果x小于根节点,那么搜索左子树
如果x大于根节点,那么搜索右子树
二叉搜索树所需要进行的操作次数最多与树的深度相等。n个节点的二叉搜索树的深度最多为n,最少为log(n)
树模板 python 1 2 3 4 5 class TreeNode: def __init__(self, val=0 , left=None, right=None): self.val = val self.left = left self.right = right
Go 1 2 3 4 5 type TreeNode struct { Val int Left *TreeNode Right *TreeNode }
例题 前序遍历 根左右
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 type TreeNode struct { Val int Left *TreeNode Right *TreeNode } func preorderTraversal(root *TreeNode) []int { res := []int{} var handle func(*TreeNode) handle = func (root *TreeNode ) { if root == nil { return } res = append(res, root.Val) handle(root.Left) handle(root.Right) } handle(root) return res } func preorderTraversal(root *TreeNode) []int { stack := []*TreeNode{} node := root res := []int{} for node != nil || len(stack) > 0 { for node != nil { res = append(res, node.Val) stack = append(stack, node) node = node.Left } node = stack[len(stack) - 1 ].Right stack = stack[:len(stack) - 1 ] } return res }
中序遍历 左根右
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 type TreeNode struct { Val int Left *TreeNode Right *TreeNode } func inorderTraversal(root *TreeNode) []int { res := []int{} var handle func(*TreeNode) handle = func (root *TreeNode ) { if root == nil { return } handle(root.Left) res = append(res, root.Val) handle(root.Right) } handle(root) return res } func inorderTraversal(root *TreeNode) []int { stack := []*TreeNode{} node := root res := []int{} for node != nil || len(stack) > 0 { for node != nil { stack = append(stack, node) node = node.Left } node = stack[len(stack) - 1 ] stack = stack[:len(stack) - 1 ] res = append(res, node.Val) node = node.Right } return res }
后序遍历 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 func postorderTraversal(root *TreeNode) []int { res := []int{} var handle func(root *TreeNode) handle = func (root *TreeNode ) { if root == nil { return } handle(root.Left) handle(root.Right) res = append(res, root.Val) } handle(root) return res } func postorderTraversal(root *TreeNode) []int { stack := []*TreeNode{} var prev *TreeNode res := []int{} for root != nil || len(stack) > 0 { for root != nil { stack = append(stack, root) root = root.Left } root = stack[len(stack) - 1 ] stack = stack[:len(stack) - 1 ] if root.Right == nil || root.Right == prev { res = append(res, root.Val) prev = root root = nil } else { stack = append(stack, root) root = root.Right } } return res }
从前序中序构造二叉树 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 type TreeNode struct { Val int Left *TreeNode Right *TreeNode } func buildTree(preorder []int, inorder []int) *TreeNode { if len(preorder)==0 { return nil } root:=&TreeNode{ Val:preorder[0 ], } var num int for k, v := range inorder{ if v == preorder[0 ]{ num = k break } } root.Left = buildTree(preorder[1 :num+1 ],inorder[:num]) root.Right = buildTree(preorder[num+1 :],inorder[num+1 :]) return root }
N叉树的前序 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 type Node struct { Val int Children []*Node } var res []intfunc preorder(root *Node) []int { res = []int{} handle(root) return res } func handle (root *Node ) { if root != nil { res = append(res, root.Val) for _, v := range root.Children { handle(v) } } } func preorder(root *Node) []int { var res []int var stack = []*Node{root} for 0 < len (stack ) { for root != nil { res = append(res, root.Val) if 0 == len (root.Children ) { break } for i := len(root.Children) - 1 ; 0 < i; i-- { stack = append(stack, root.Children[i]) } root = root.Children[0 ] } root = stack[len(stack)-1 ] stack = stack[:len(stack)-1 ] } return res } func preorder(root *Node) []int { res := []int{} if root == nil { return res } stack := []*Node{root} for len(stack) > 0 { node := stack[len(stack) - 1 ] stack = stack[:len(stack) - 1 ] res = append(res, node.Val) for i := len(node.Children) - 1 ; i >= 0 ; i-- { stack = append(stack, node.Children[i]) } } return res }
二叉树的最近公共祖先 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 type TreeNode struct { Val int Left *TreeNode Right *TreeNode } func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { if root == nil || p == root || q == root { return root } left := lowestCommonAncestor(root.Left, p, q) right := lowestCommonAncestor(root.Right, p, q) if left == nil { return right } if right == nil { return left } return root } func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { parent := map[int]*TreeNode{} visited := map[int]bool{} var dfs func(*TreeNode) dfs = func (r *TreeNode ) { if r == nil { return } if r.Left != nil { parent[r.Left.Val] = r dfs(r.Left) } if r.Right != nil { parent[r.Right.Val] = r dfs(r.Right) } } dfs(root) for p != nil { visited[p.Val] = true p = parent[p.Val] } for q != nil { if visited[q.Val] { return q } q = parent[q.Val] } return nil }
二叉树的最大深度 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 func maxDepth(root *TreeNode) int { if root == nil { return 0 } return max(maxDepth(root.Left), maxDepth(root.Right)) + 1 } func max(a, b int) int { if a > b { return a } return b } func maxDepth(root *TreeNode) int { var res int if root == nil { return res } var dfs func(*TreeNode, int) dfs = func (root *TreeNode, l int ) { if l == res { res++ } if root.Left != nil { dfs(root.Left, l+1 ) } if root.Right != nil { dfs(root.Right, l+1 ) } } dfs(root, 0 ) return res } func maxDepth(root *TreeNode) int { if root == nil { return 0 } q := []*TreeNode{root} res := 0 for len(q) > 0 { l := len(q) for l > 0 { node := q[0 ] q = q[1 :] if node.Left != nil { q = append(q, node.Left) } if node.Right != nil { q = append(q, node.Right) } l-- } res++ } return res }
N叉树的层序遍历 第一层循环的是每一层,获取当前层的长度,初始化临时结果,然后下一层遍历这个结果
然后出队,取出节点,遍历节点的children下一层,下一层的入队,上一层会遍历完按顺序出队
下一层的都入队之后,上一层的都出队,加入结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 func levelOrder(root *Node) [][]int { var res [][]int if root == nil { return res } q := []*Node{root} for len(q) > 0 { l := len(q) levelRes := []int{} for l > 0 { node := q[0 ] q = q[1 :] if len(node.Children) != 0 { for _, v := range node.Children { q = append(q, v) } } levelRes = append(levelRes, node.Val) l-- } res = append(res, levelRes) } return res } func levelOrder(root *Node) [][]int { res := [][]int{} var dfs func(int, *Node) dfs = func (l int, root *Node ) { if l == len (res ) { res = append(res, []int{}) } res[l] = append(res[l], root.Val) for i := 0 ; i < len(root.Children); i++ { dfs(l+1 , root.Children[i]) } } if root != nil { dfs(0 , root) } return res }
二叉树的层序遍历 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 func levelOrder(root *TreeNode) [][]int { res := [][]int{} if root == nil { return res } var dfs func(*TreeNode, int) dfs = func (root *TreeNode, l int ) { if l == len (res ) { res = append(res, []int{}) } res[l] = append(res[l], root.Val) if root.Left != nil {dfs(root.Left, l+1 )} if root.Right != nil {dfs(root.Right, l+1 )} } dfs(root, 0 ) return res } func levelOrder(root *TreeNode) [][]int { res := [][]int{} if root == nil { return res } q := []*TreeNode{root} for len(q) > 0 { l := len(q) lCur := []int{} for i := 0 ; i < l; i++ { node := q[0 ] q = q[1 :] lCur = append(lCur, node.Val) if node.Left != nil {q = append(q, node.Left)} if node.Right != nil {q = append(q, node.Right)} } res = append(res, lCur) } return res }