【数据结构和算法】_05_树 & 图


 


【一】 Tree(树)

  • 结构
  • 代码 创建树
# python
class TreeNode:
	def __init__(self, val):
		self.val = val
		self.left, self.right = None, None
// c++
struct TreeNode {
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x):val(x), left(NULL), right(NULL) {}
}

 
 

【1.1】 Complete Binary Tree(完全二叉树)

 
 

【1.2】 Binary Search Tree(二叉搜索树)
  • 左子树 上的 所有节点 的值均 小于 它的 根节点 的值
  • 右子树 上的 所有节点 的值均 大于 它的 根节点 的值
  • 递归的,左右子树也分别为二叉搜索树
  • 查找(O ( logN ))

 
 

【1.3】 B Tree(B树,B减树,平衡多路查找树)
  • 高级的 二叉平衡树,主要用于查找磁盘中的大量数据
  • 若 根节点 不是 叶子节点,则至少有2棵子树
  • 除 根节点 以外的所有 非叶节点 至少有 M/2 棵子树,至多有 M 个子树(M阶)
  • 所有的 叶子节点都位于同一层

 
 

【1.4】 B+ Tree(B+ 树)
  • 高级的 B树,比 B树 的查询性能更高
  • 叶子节点包含了全部数据,拥有指针链接,同时符合左小右大的顺序

【二】 Garph(图)

  • 结构

【三】 Interview(面试题)

【3.1】 LeetCode 98:Validate BST(验证二叉搜索树)

Input: [ 2, 1, 5, null, null, 2 ]
Output: true
 
Input: [ 5, 1, 4, null, null, 3, 6 ]
Output: false

  • In-Order(中序遍历)
# python 1 (很好理解)

def isValidBST(self, root):
	inorder = self.inorder(root)
	return inorder == list(sorted(set(inorder)))

# 中序遍历,左,根,右
def inorder(self, root):
	if root is None:
		return []
	return self.inorder(root.left) + [root.val] + self.inorder(root.right)
# python 2 (不太能很好的理解)

def isValidBST(self, root):
	self.prev = None
	return self.helper(root)

# 中序遍历,左,根,右
def helper(self, root):
	if root is None:
		return True
	# 左
	if not self.helper(root.left):
		return False
	# 判断当前节点和前继节点的大小
	if self.prev and self.prev.val >= root.val:
		return False
	self.prev = root
	# 右
	return self.helper(root.right)
  • Recursion(递归)
// java (巧妙设置了 最小值min 和 最大值max)

public boolean isValid(TreeNode root, Integer min, Integer max) {
	if (root == null) return true;
	// 如果当前的值比最小值还小,那就不对了
	if (min != null && root.val <= min) return false;
	// 如果当前的值比最大值还大,那也不对了
	if (max != null && root.val >= max) return false;
	// 巧妙地利用了最大值和最小值,来判断左右子树
	return isValid(root.left, min, root.val) && isValid(root.right, root.val, max);
}

 
 

【3.2】 LeetCode 236,235:Lowest Common Ancestor(二叉树 / 二叉搜索树的最近公共祖先)

Input: root = [ 6, 2, 8, 0, 4, 7, 9, null, null, 3, 5 ],p = 2,q = 8
Output: 6
 
Input: root = [ 6, 2, 8, 0, 4, 7, 9, null, null, 3, 5 ],p = 2,q = 4
Output: 2

  • Recursion递归 - 任意的二叉树
// java (不好理解)

TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
	if (root == null || root == p || root == q) return root;
	// 左子树
	TreeNode left = lowestCommonAncestor(root.left, p, q);
	// 右子树
	TreeNode right = lowestCommonAncestor(root.right, p, q);
	// 如果左子树为空,说明 p 和 q 都在右子树,返回右子树
	// 如果右子树为空,说明 p 和 q 都在左子树,返回左子树
	// 如果左右子树都不为空,说明分别在左右子树里,返回其 root
	return left == null ? right : right == null ? left : root;
}
  • Recursion递归 - 二叉搜索树
# python 1

def lowestCommonAncestor(self, root, p, q):
	# 如果 p 和 q 都小于 root,那么说明都在左子树里
	if p.val < root.val > q.val:
		return self.lowestCommonAncestor(root.left, p, q)
	# 如果 p 和 q 都大于 root,那么说明都在右子树里
	if p.val > root.val < q.val:
		return self.lowestCommonAncestor(root.right, p, q)
	# 最后返回 root 就行
	return root
  • Unrecursion非递归 - 二叉搜索树
# python 2 (思路和上面一样)

def lowestCommonAncestor(self, root, p, q):
	while root:
		# 如果 p 和 q 都小于 root,那么说明都在左子树里
		if p.val < root.val > q.val:
			root = root.left
		# 如果 p 和 q 都大于 root,那么说明都在右子树里
		elif p.val > root.val < q.val:
			root = root.right
		# 最后返回 root 就行
		else: return root
发布了57 篇原创文章 · 获赞 5 · 访问量 2873

猜你喜欢

转载自blog.csdn.net/qq_34330456/article/details/104482666