树的遍历
- 前序遍历(pre-order): 根 左 右
- 中序遍历(in-order): 左 根 右
- 后序遍历(post-order): 左 右 根
树
- 父亲节点、儿子节点、层高
二叉树
- 只有2个儿子结点
示例代码
遍历的写法
class TreeDemo(object):
def __init__(self, val):
self.val = val
self.left = None
self.right = None
# 前序遍历 pre-order
# 根 左 右
def preorder(self, root):
if root:
self.travel_path.append(root.val)
self.preorder(root.left)
self.preorder(root.right)
# 中序遍历 in-order
# 左 根 右
def inorder(self, root):
if root:
self.preorder(root.left)
self.travel_path.append(root.val)
self.preorder(root.right)
# 后序遍历 post-order
# 左 右 根
def postorder(self, root):
if root:
self.preorder(root.left)
self.preorder(root.right)
self.travel_path.append(root.val)
二叉搜索树(binary search tree)
定义:
- 有序的二叉树
- 如果任意节点的左子树不能为空, 左子树所有的节点的值 小于 它的根节点的值
- 如果任意节点的右子树不能为空, 右子树所有的节点的值 大于 它的根节点的值
- 以此类推 左右子树 都是二叉搜索树
- 左子树中所有节点的值 < 根节点的值 < 右子树中所有节点的值
- 复杂度
- 搜索 O(logn)
- 插入 O(logn)
- 删除 O(logn)
- 中序遍历是一个生序遍历
查找
visualgo.net/zh/bst (logn) 和根节点对比 每次可以排除一半的空间
插入新节点
(logn)
- 先进行查找 如果找不到 就在最后部分插入节点
删除
(logn)
- 如果是叶子节点
- 如果是跟节点 或者 子树的根节点
例如要删除65
应该找一个65 相近的节点进行补位 要么是左子树中最大的节点 要么是右子树中最小的节点
默认找右子树中最小的节点
例如删除41
图
- 特殊的树 形成了环路