zoukankan      html  css  js  c++  java
  • 树与二叉树

    python实现树与二叉树的代码:
    #创建二叉树的类
    class BiTreeNode:
    def __init__(self,data):
    self.data=data
    self.lchild=None #左孩子
    self.rchild=None #右孩子

    a=BiTreeNode("A")
    b=BiTreeNode("B")
    c=BiTreeNode("C")
    d=BiTreeNode("D")
    e=BiTreeNode("E")
    f=BiTreeNode("F")
    g=BiTreeNode("G")

    e.lchild=a
    e.rchild=g
    a.rchild=c
    c.lchild=b
    c.rchild=d
    g.rchild=f
    root=e

    print(root.lchild.rchild.data)

    #二叉树的遍历方式
    #前序遍历:根节点在前面
    def pre_order(root):
    if root:
    print(root.data,end=",") #先访问根节点
    pre_order(root.lchild) #再访问左子树
    pre_order(root.rchild) #再访问右边=子树
    pre_order(root)
    print()

    #中序遍历:根节点在中间
    def in_order(root):
    if root:
    in_order(root.lchild)
    print(root.data,end=",")
    in_order(root.rchild)
    in_order(root)
    print()

    #后续遍历:根节点在最后面
    def post_order(root):
    if root:
    post_order(root.lchild)
    post_order(root.rchild)
    print(root.data, end=",")
    post_order(root)
    print()

    #层次遍历:使用队列来进行输出
    from collections import deque
    def level_order(root):
    quede=deque()
    quede.append(root)
    while len(quede)>0:
    node=quede.popleft()
    print(node.data,end=",")
    if node.lchild:
    quede.append(node.lchild)
    if node.rchild:
    quede.append(node.rchild)
    level_order(root)
    print()

    #二叉搜索树的插入,删除和查询
    #插入
    #先定义节点的类别
    class BiTreeNode1:
    def __init__(self,data):
    self.data=data
    self.lchild=None #左孩子
    self.rchild=None #右孩子
    self.parent=None #父亲节点
    class BST:
    def __init__(self,li=None):
    self.root=None
    if li:
    for var in li:
    self.insert_1(var)
    #递归插入
    def insert(self,node,val):
    if not node:
    node=BiTreeNode1(val)
    elif val<node.data:
    node.lchild=self.insert(node.lchild,val)
    node.lchild.parent=node
    elif val>node.data:
    node.rchild=self.insert(node.rchild,val)
    node.rchild.parent=node
    return node
    #非递归插入,循环插入
    def insert_1(self,val):
    p=self.root
    if not p: #空树情况下
    self.root=BiTreeNode1(val)
    return
    while True:
    if val< p.data:
    if p.lchild:
    p=p.lchild
    else: #左孩子不存在
    p.lchild=BiTreeNode1(val)
    p.lchild.parent=p
    elif val>p.data:
    if p.rchild:
    p=p.rchild
    else:
    p.rchild=BiTreeNode1(val)
    p.rchild.parent=p
    else:
    return

    #查询(递归查询)
    def query(self,node,var):
    if not node:
    return None
    if node.data<var:
    return self.query(node.rchild,var)
    elif node.data>var:
    return self.query(node.lchild,var)
    else:
    return node
    #非递归查询
    def query1(self,var):
    p=self.root
    while p:
    if p.data<var:
    p=p.rchild
    elif p.data>var:
    p=p.lchild
    else:
    return p
    return None

    #前序遍历
    def pre_order(self,root):
    if root:
    print(root.data, end=",") # 先访问根节点
    self.pre_order(root.lchild) # 再访问左子树
    self.pre_order(root.rchild) # 再访问右边=子树

    # 中序遍历:根节点在中间
    def in_order(self,root):
    if root:
    self.in_order(root.lchild)
    print(root.data, end=",")
    self.in_order(root.rchild)

    # 后续遍历:根节点在最后面
    def post_order(self,root):
    if root:
    self.post_order(root.lchild)
    self.post_order(root.rchild)
    print(root.data, end=",")

    #节点删除操作分情况讨论
    def _remove_node_1(self,node):
    #1node是叶子节点的
    if not node.parent: #如果是根节点的话
    self.root=None
    if node==node.parent.lchild: #node是它父亲的左孩子
    node.parent.lchild=None
    else: #有孩子
    node.parent.rchild=None
    def _remove_noded_21(self,node):
    #情况2:node只有一个左孩子
    if not node.parent: #根节点
    self.root=node.lchild
    node.lchild.parent=None
    #根据node节点是自己父亲的左节点还是有右节点分类
    elif node==node.parent.lchild: #node是左孩子的话
    node.parent.lchild=node.lchild
    node.lchild.parent=node.parent
    else:
    node.parent.rchild=node.lchild
    node.lchild.parent=node.parent
    def _remove_node_22(self,node):
    #node只有一个右孩子的话
    if not node.parent: #node是节点
    self.root=node.rchild
    elif node==node.parent.lchild: #node是左孩子的话
    node.parent.lchild=node.rchild
    node.rchild.parent=node.parent
    else:
    node.parent.rchild=node.rchild
    node.rchild.parent=node.parent

    #删除操作总封装函数
    def delete(self,val):
    if self.root:
    node=self.query1(val) #遍历查询,如果存在,返回node节点
    if not node: #如果不存在节点
    return False
    if not node.lchild and node.rchild: #判断如果没有孩子,情况1
    self._remove_node_1(node)
    elif not node.rchild: #只有一个左孩子,情况2
    self._remove_noded_21(node)
    elif not node.lchild: #只有一个右孩子
    self._remove_node_22(node)
    else: #两个孩子
    min_node=node.rchild
    while min_node.lchild:
    min_node=min_node.lchild
    node.data=min_node.data #将右子树的最左边的节点值赋值给node节点
    if min_node.rchild:
    self._remove_node_22(min_node)
    else:
    self._remove_node_1(min_node)

    import random
    li=list(range(20))
    li1=[random.randint(0,100) for _ in range(20)]
    random.shuffle(li)

    tree=BST(li)
    tree.pre_order(tree.root)
    print()
    tree.in_order(tree.root) #中序遍历是排好序的
    print()

    
    
  • 相关阅读:
    移动应用专项测试
    MAC连接安卓手机通过adb指令安装apk
    Git GUI可视化操作教程
    nestjs中typeorm进行事物操作
    vue-element-admin 实现动态路由(从后台查询出菜单列表绑定侧边栏)
    el-form 表单校验
    vscode设置VUE eslint开发环境
    .netcore signalR 实时消息推送
    psexec局域网执行远程命令
    Asp.Net跨平台 Jexus 5.8.1 独立版
  • 原文地址:https://www.cnblogs.com/Yanjy-OnlyOne/p/12450594.html
Copyright © 2011-2022 走看看