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

    为了准备面试,早就学习了二叉树,最近想撸一下红黑树。先把二叉树给总结一下吧。

    1.二叉树定义

    在计算机科学中,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。

    图中就是一个典型的二叉树。

    2.二叉树的一些概念

    树的结点(node):包含一个数据元素及若干指向子树的分支;
    孩子结点(child node):结点的子树的根称为该结点的孩子;
    双亲结点:B 结点是A 结点的孩子,则A结点是B 结点的双亲;
    兄弟结点:同一双亲的孩子结点; 堂兄结点:同一层上结点;
    祖先结点: 从根到该结点的所经分支上的所有结点
    子孙结点:以某结点为根的子树中任一结点都称为该结点的子孙
    结点层:根结点的层定义为1;根的孩子为第二层结点,依此类推;
    树的深度:树中最大的结点层
    结点的度:结点子树的个数
    树的度: 树中最大的结点度。
    叶子结点:也叫终端结点,是度为 0 的结点;
    分枝结点:度不为0的结点;
    有序树:子树有序的树,如:家族树;
    无序树:不考虑子树的顺序;
    ----------------回头更新--------
     3.二叉树的可视化
    要学习二叉树,利用python来构建二叉树,首先要有一个办法能将二叉树可视化。这我找了不少地方,最后不记得在哪找到了一个方法使用networkx和matplotlib来进行绘制。
    import networkx as nx
    import matplotlib.pyplot as plt
    
    def create_graph(G, node, pos={}, x=0, y=0, layer=1):
        pos[node.key] = (x, y)
        if node.left:
            G.add_edge(node.key, node.left.key)
            l_x, l_y = x - 1 / 2 ** layer, y - 1
            l_layer = layer + 1
            create_graph(G, node.left, x=l_x, y=l_y, pos=pos, layer=l_layer)
        if node.right:
            G.add_edge(node.key, node.right.key)
            r_x, r_y = x + 1 / 2 ** layer, y - 1
            r_layer = layer + 1
            create_graph(G, node.right, x=r_x, y=r_y, pos=pos, layer=r_layer)
        return (G, pos)
    
    def draw(node):   # 以某个节点为根画图
        graph = nx.DiGraph()
        graph, pos = create_graph(graph, node)
        fig, ax = plt.subplots(figsize=(8, 10))  # 比例可以根据树的深度适当调节
        nx.draw_networkx(graph, pos, ax=ax, node_size=600)
        plt.show()

    调用的时候,使用draw(tree.root)就可以将整个树绘制出来,如下图所示

     

    4.二叉树的构建

    这个没啥好说的,基本就是构建一个节点类作为节点,有左枝和右枝,值,父节点四个属性;还有一个树类,要求要有节点的增,删,查功能。

    增:增加一个元素就是从根节点开始,不断对比节点与插入的值,最后找到所在的位置新增一个节点

    查:从根节点开始不断向下查找。

    删:这个比较麻烦,需要分三种情况讨论:

    4.1所删除的节点是叶子节点,直接删除就可以了。

    4.2所删除的节点有一个分支,那么就使用它的分支的第一个节点代替它就好了

    4.3所删除的节点有两个分支,那么要查找它的最小后继(一定在它的右枝里)然后替换它,再删除原来的最小后继(注意,这个再删除是一个递归过程)

    构建代码如下

    class node(object):
        def __init__(self,value):
            self.key=value
            self.right=None
            self.left=None
            self.parent=None
    
    class tree(object):
        def __init__(self):
            self.root=None
            self.nodeArr=[]
        def add(self,element):
            newNode=node(element)
    
            if self.root:
                index=self.root
                lastIndex=index
                while index!=None:
                    lastIndex = index
                    if index.key <element:
                        index=index.right
                    else :
                        index=index.left
                if lastIndex.key < element:
                    lastIndex.right=newNode
                    newNode.parent =lastIndex
                else:
                    lastIndex.left=newNode
                    newNode.parent = lastIndex
            else:
                self.root= newNode
    
        def find(self,element,root):
            temp=root
            while temp:
                if temp.key<element:
                    temp=temp.right
                elif temp.key>element:
                    temp=temp.left
                else:
                    return temp
        def maxNode(self,node):
            temp=node
            while temp.right:
                temp=temp.right
            return temp
        def minNode(self,node):
            temp=node
            while temp.left:
                temp=temp.left
            return temp
        def remove(self,element,root):
            temp=self.find(element,root)
            print(temp)
            if temp:
                newNode=None
                del_node=temp
                if temp.right and temp.left:#如果有两个分支
                    rightMax = self.maxNode(temp)
                    newNode=node(rightMax.key)
    
                    newNode.parent=del_node.parent
                    del_node.parent.right=newNode
    
                    newNode.left=del_node.left
                    if del_node.left:
                        del_node.left.parent=newNode
                    newNode.right = del_node.right
                    if del_node.right:
                        del_node.right.parent = newNode
                    del del_node
                    self.remove(newNode.key,newNode.right)
    
                elif not temp.right and not temp.left:#没有分支
                    del_node.parent.right=None
                    del del_node
    
                else :#只有一个分支
                    value=temp.right or temp.left
                    value.parent=del_node.parent
                    if del_node.parent.right.key==temp.key:
                        value.parent.right=value
                    else:
                        value.parent.left=value
                    del del_node

    5.整体效果

    运行以下代码,可以看到删除节点335前和删除节点335以后的效果。

    myTree=tree()
    s=[149, 382, 364, 335, 35, 498, 370, 272, 327, 191]
    for i in range(10):
        myTree.add(s[i])
    
    draw(myTree.root)
    myTree.remove(335,myTree.root)#删除335节点
    draw(myTree.root)

  • 相关阅读:
    Windows XP下 Android开发环境 搭建
    Android程序的入口点
    在eclipse里 新建android项目时 提示找不到proguard.cfg
    64位WIN7系统 下 搭建Android开发环境
    在eclipse里 新建android项目时 提示找不到proguard.cfg
    This Android SDK requires Android Developer Toolkit version 20.0.0 or above
    This Android SDK requires Android Developer Toolkit version 20.0.0 or above
    Android requires compiler compliance level 5.0 or 6.0. Found '1.4' instead
    Windows XP下 Android开发环境 搭建
    Android程序的入口点
  • 原文地址:https://www.cnblogs.com/NewsunLs/p/10069238.html
Copyright © 2011-2022 走看看