数据结构--二叉树/堆
1. 二叉树
二叉树的相关理论性质,可以查看以下链接:
https://www.cnblogs.com/skywang12345/p/3576328.html
1.1 二叉查找树的插入、删除、查找:
定义二叉树节点
class BSTreeNode:
def __init__(self,data):
self.data=data
self.left=None
self.right=None
实现一个二叉查找树,并且支持插入、删除、查找操作
class BSTree:
def __init__(self,node_list):
self.root=BSTreeNode(node_list[0])
for data in node_list[1:]:
self.BSTreeInsert(data)
#print(data)
def BSTreeSearch(self,node, parent,data):
if node is None:
return False, node, parent #若为空,则已为叶子节点(或者单一的根节点)
if node.data==data: # 在原有的二叉搜索树中,找到了该节点了,则不再创建新节点
return True, node, parent
if node.data>data:
return self.BSTreeSearch(node.left,node,data)
else:
return self.BSTreeSearch(node.right,node,data)
#插入节点
def BSTreeInsert(self,data):
flag, n, p = self.BSTreeSearch(self.root, self.root, data)
if not flag:
new_node = BSTreeNode(data)
if data > p.data:
p.right = new_node
else:
p.left = new_node
def PrintTree(self,node,data,direction):
'''
# * 打印"二叉树"
# *
# * tree -- 二叉树的节点
# * key -- 节点的键值
# * direction -- 0,表示该节点是根节点;
# * -1,表示该节点是它的父结点的左孩子;
# * 1,表示该节点是它的父结点的右孩子。
'''
if node !=None:
if direction==0:
print("%d is root"%(node.data))
elif direction==1:
print("%d is %d's right child"%(node.data,data))
else:
print("%d is %d's left child"%(node.data,data))
self.PrintTree(node.left,node.data,-1)
self.PrintTree(node.right,node.data,1)
if __name__ == '__main__':
lista=[49, 38, 65, 97, 60, 76, 13, 27, 5, 1]
bst=BSTree(lista)
print("the detail information of this BSTree is: ")
bst.PrintTree(bst.root,bst.root.data,0)
1.2 二叉树的遍历
实现二叉树前、中、后序以及按层遍历
# 先序遍历 前序遍历:根结点 ---> 左子树 ---> 右子树
def preOrderTraverse(self, node):
if node is not None:
print (node.data)
self.preOrderTraverse(node.left)
self.preOrderTraverse(node.right)
#中序遍历:左子树---> 根结点 ---> 右子树
def InOrderTraverse(self, node):
if node is not None:
self.preOrderTraverse(node.left)
print (node.data)
self.preOrderTraverse(node.right)
#后序遍历:左子树 ---> 右子树 ---> 根结点
def PostOrderTraverse(self,node):
if node is not None:
self.preOrderTraverse(node.left)
self.preOrderTraverse(node.right)
print (node.data)
1.3 查找某个节点的后继、前驱节点
任务:实现查找二叉查找树中某个节点的后继、前驱节点
节点的前驱:是该节点的左子树中的最大节点。
节点的后继:是该节点的右子树中的最小节点。
1.3.1查找前驱节点
前驱节点
- 若一个节点有左子树,那么该节点的前驱节点是其左子树中val值最大的节点(也就是左子树中所谓的rightMostNode)
- 若一个节点没有左子树,那么判断该节点和其父节点的关系
(1)若该节点是其父节点的右边孩子,那么该节点的前驱结点即为其父节点。
(2) 若该节点是其父节点的左边孩子,那么需要沿着其父亲节点一直向树的顶端寻找,直到找到一个节点P,P节点是其父节点Q的右边孩子(可参考例子2的前驱结点是1),那么Q就是该节点的后继节点
def Find_BSTreeMax(self,node): # 查找最大值
# node=self.root
if node==None:
return None
while node.right!=None:
node=node.right
return node
def BSTree_Predecessor(self,node):
# 如果x存在左孩子,则"x的前驱结点"为 "以其左孩子为根的子树的最大结点"
if node.left!=None:
return self.Find_BSTreeMax(node.left)
#如果x没有左孩子。则x有以下两种可能:
# (01) x是"一个右孩子",则"x的前驱结点"为 "它的父结点"。
# (02) x是"一个左孩子",则查找"x的最低的父结点,并且该父结点要具有右孩子",找到的这个"最低的父结点"就是"x的前驱结点"。
node_parent=node.parent
while node_parent!=None and node==node_parent.left :
node=node_parent
node_parent=node_parent.parent
return node_parent
1.3.2 查找后继节点
节点的后继:是该节点的右子树中的最小节点。
后继节点
- 若一个节点有右子树,那么该节点的后继节点是其右子树中val值最小的节点(也就是右子树中所谓的leftMostNode)
- 若一个节点没有右子树,那么判断该节点和其父节点的关系
(1)若该节点是其父节点的左边孩子,那么该节点的后继结点即为其父节点
(2)若该节点是其父节点的右边孩子,那么需要沿着其父亲节点一直向树的顶端寻找,直到找到一个节点P,P节点是其父节点Q的左边孩子(可参考例子2的前驱结点是1),那么Q就是该节点的后继节点
def Find_BSTreeMin(self,node): # 查找最小值
if node==None:
return None
while node.left!=None:
node=node.left
return node
def BSTree_successor(self,node):
# 如果x存在右孩子,则"x的后继结点"为 "以其右孩子为根的子树的最小结点"。
if node.right!=None:
return self.Find_BSTreeMin(node.right)
# 如果x没有右孩子。则x有以下两种可能:
# (01) x是"一个左孩子",则"x的后继结点"为 "它的父结点"。
# (02) x是"一个右孩子",则查找"x的最低的父结点,并且该父结点要具有左孩子",找到的这个"最低的父结点"就是"x的后继结点"。
node_parent=node.parent
while node_parent!=None and node==node_parent.right :
node=node_parent
node_parent=node_parent.parent
return node_parent
参考链接
https://www.cnblogs.com/skywang12345/p/3576328.html
1.4 二叉搜索树
并完成leetcode上的验证二叉搜索树(98)及二叉树 层次遍历(102,107)!(选做)参考链接:
https://www.cnblogs.com/linxiyue/p/3624597.html
https://blog.csdn.net/liangjiubujiu/article/details/82794095
2. 堆
以上内容来自以下链接:
https://www.cnblogs.com/chengxiao/p/6129630.html
2.1 堆排序
实现堆排序
2.2 求Top K
利用优先级队列合并 K 个有序数组
求一组动态数据集合的最大 Top K
对应的 LeetCode 练习题
Invert Binary Tree(翻转二叉树)
英文版:https://leetcode.com/problems/invert-binary-tree/
中文版:https://leetcode-cn.com/problems/invert-binary-tree/
Maximum Depth of Binary Tree(二叉树的最大深度)
英文版:https://leetcode.com/problems/maximum-depth-of-binary-tree/
中文版:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/
Validate Binary Search Tree(验证二叉查找树)
英文版:https://leetcode.com/problems/validate-binary-search-tree/
中文版:https://leetcode-cn.com/problems/validate-binary-search-tree/
Path Sum(路径总和)
英文版:https://leetcode.com/problems/path-sum/
中文版:https://leetcode-cn.com/problems/path-sum/