二叉树的构建和遍历
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 74 75 76 77 78 79 80 81 82 83 84
| class TreeNode: def __init__(self, x): self.val = x self.left = None self.right = None
class BinaryTree: def __init__(self, data): self.data = data self.root = self.create(None, 0) self.traversal = [] def create(self, root, i): if(i >= len(self.data)): return root root = TreeNode(self.data[i]) root.left = self.create(root.left, 2 * i + 1) root.right = self.create(root.right, 2 * i + 2) return root def preorder_recur(self, root): if(not root): return self.traversal.append(root.val) self.preorder_recur(root.left) self.preorder_recur(root.right) def preorder_unrecur(self, root): stack = [] p = root while(stack or p): while(p): self.traversal.append(p.val) stack.append(p) p = p.left p = stack.pop() p = p.right def inorder_recur(self, root): if(not root): return self.inorder_recur(root.left) self.traversal.append(root.val) self.inorder_recur(root.right) def inorder_unrecur(self, root): stack = [] p = root while(stack or p): while(p): stack.append(p) p = p.left p = stack.pop() self.traversal.append(p.val) p = p.right def postorder_recur(self, root): if(not root): return self.postorder_recur(root.left) self.postorder_recur(root.right) self.traversal.append(root.val) def postorder_unrecur(self, root): stack = [] p = root while(stack or p): while(p): self.traversal.append(p.val) stack.append(p) p = p.right p = stack.pop() p = p.left self.traversal = self.traversal[::-1]
|
运行结果
1 2 3 4 5 6 7 8 9 10 11 12 13
| bTree = BinaryTree([30, 24, 46, 15, 27, 2, 6, 17, 4, 8, 29])
bTree.traversal = [] bTree.preorder_recur(bTree.root) print(bTree.traversal)
bTree.traversal = [] bTree.preorder_unrecur(bTree.root) print(bTree.traversal)
>>> [30, 24, 15, 17, 4, 27, 8, 29, 46, 2, 6] >>> [30, 24, 15, 17, 4, 27, 8, 29, 46, 2, 6]
|
1 2 3 4 5 6 7 8 9 10 11
| bTree.traversal = [] bTree.inorder_recur(bTree.root) print(bTree.traversal)
bTree.traversal = [] bTree.inorder_unrecur(bTree.root) print(bTree.traversal)
>>> [17, 15, 4, 24, 8, 27, 29, 30, 2, 46, 6] >>> [17, 15, 4, 24, 8, 27, 29, 30, 2, 46, 6]
|
1 2 3 4 5 6 7 8 9 10 11
| bTree.traversal = [] bTree.postorder_recur(bTree.root) print(bTree.traversal)
bTree.traversal = [] bTree.postorder_unrecur(bTree.root) print(bTree.traversal)
>>> [17, 4, 15, 8, 29, 27, 24, 2, 6, 46, 30] >>> [17, 4, 15, 8, 29, 27, 24, 2, 6, 46, 30]
|
算法题案例
重建二叉树
题目来源:剑指Offer
题目链接:牛客网-剑指Offer
题目描述:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。
解题思路
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
|
class Solution: def __init__(self): self.traversal = []
def postorder_recur(self, root): if(not root): return self.postorder_recur(root.left) self.postorder_recur(root.right) self.traversal.append(root.val) def reConstructBinaryTree(self, pre, tin): if(not pre or not tin): return None
root = TreeNode(pre[0]) rootIdx = tin.index(root.val)
tinLeft = tin[:rootIdx] preLeft = pre[1:len(tinLeft) + 1] root.left = self.reConstructBinaryTree(preLeft, tinLeft)
tinRight = tin[rootIdx + 1:] preRight = pre[len(tinLeft) + 1:] root.right = self.reConstructBinaryTree(preRight, tinRight) return root
|
运行结果
重建二叉树后,利用前文二叉树的后序遍历算法,进行验证
1 2 3 4 5 6 7
| S = Solution() root = S.reConstructBinaryTree([1,2,4,7,3,5,6,8], [4,7,2,1,5,3,8,6])
S.postorder_recur(root) print(S.traversal)
>>> [7, 4, 2, 5, 8, 6, 3, 1]
|
二叉树的镜像
题目来源:剑指Offer & Leetcode
题目链接:牛客网-剑指Offer、Leetcode-226
题目描述:
操作给定的二叉树,将其变换为源二叉树的镜像。
输入描述:
解题思路
运行结果
二叉搜索树与双向链表
题目来源:剑指Offer
题目链接:牛客网-剑指Offer
题目描述:
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
解题思路
运行结果
二叉树的所有路径
题目来源:Leetcode
题目链接:Leetcode-257
题目描述:
给定一个二叉树,返回所有从根节点到叶子节点的路径。
说明: 叶子节点是指没有子节点的节点。
示例:
解题思路
运行结果
二叉树中和为某一值的路径
题目来源:剑指Offer
题目链接:牛客网-剑指Offer
题目描述:
输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。(注意: 在返回值的list中,数组长度大的数组靠前)
解题思路
运行结果
二叉搜索树的后序遍历序列
题目来源:剑指Offer
题目链接:牛客网-剑指Offer
题目描述:
输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。
解题思路
运行结果
从上往下打印二叉树
题目来源:剑指Offer & Leetcode
题目链接:牛客网-剑指Offer、Leetcode-102、Leetcode-107
题目描述:
从上往下打印出二叉树的每个节点,同层节点从左至右打印。
解题思路
运行结果
平衡二叉树
题目来源:剑指Offer
题目链接:牛客网-剑指Offer
题目描述:
输入一棵二叉树,判断该二叉树是否是平衡二叉树。
解题思路
运行结果
二叉树的深度
题目来源:剑指Offer
题目链接:牛客网-剑指Offer
题目描述:
输入一棵二叉树,求该树的深度。从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。
解题思路
运行结果
按之字形顺序打印二叉树
题目来源:剑指Offer
题目链接:牛客网-剑指Offer
题目描述:
请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。
解题思路
运行结果
对称的二叉树
题目来源:剑指Offer
题目链接:牛客网-剑指Offer
题目描述:
请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。
解题思路
运行结果
把二叉树打印成多行
题目来源:剑指Offer
题目链接:牛客网-剑指Offer
题目描述:
从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。
解题思路
运行结果
二叉树的下一个结点
题目来源:剑指Offer
题目链接:牛客网-剑指Offer
题目描述:
给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。
解题思路
运行结果
序列化二叉树
题目来源:剑指Offer
题目链接:牛客网-剑指Offer
题目描述:
请实现两个函数,分别用来序列化和反序列化二叉树
二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
解题思路
运行结果
二叉搜索树的第k个结点
题目来源:剑指Offer
题目链接:牛客网-剑指Offer
题目描述:
给定一棵二叉搜索树,请找出其中的第k小的结点。例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。
解题思路
运行结果