二叉树/堆

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查找前驱节点

前驱节点

  1. 若一个节点有左子树,那么该节点的前驱节点是其左子树中val值最大的节点(也就是左子树中所谓的rightMostNode)
  2. 若一个节点没有左子树,那么判断该节点和其父节点的关系
    (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 查找后继节点

节点的后继:是该节点的右子树中的最小节点。

后继节点

  1. 若一个节点有右子树,那么该节点的后继节点是其右子树中val值最小的节点(也就是右子树中所谓的leftMostNode)
  2. 若一个节点没有右子树,那么判断该节点和其父节点的关系
    (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/

参考链接:

https://www.cnblogs.com/chengxiao/p/6129630.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值