python练习_二叉树

二叉树的自我理解

二叉树作为一个python中的典型,其实质就是一个分叉形式的数组,以一个节点开始,每次延伸出两个左右子节点,无限延伸知道没有子节点。

这些节点看似散乱,实际上是可以根据某种规律来按顺序读出来的,这就可以看做是一种专门的读取方法。假设最上级是一个总文件夹,后面的内容都是文件夹的下一级,二叉树的遍历方式就可以稳当的读出所有文件。

二叉树的遍历方式

我已知二叉树有四种遍历方式,前序,中序,后序和按层遍历。
二叉树简便示意图:
                           A
                       ↙  ↘
                     B         C
A为该节点的父节点也称为根节点,B是左子节点,C是右子节点。
其中前序的排列方式为根左右,把每三个关联的小节点综合一起看,都作为根左右的形式,如果是更多子节点的情况,看待略有复杂,但也依旧是以这种方式来看。
三层二叉树:
             A
         ↙  ↘
      B         C
   ↙ ↘    ↙ ↘
 D       E F      G
前序 :先把BDF,CFG看做是A的左右子节点,因此是从A开始读,A作为第一个,然后进到左子节点 BDE, 这时再把它看做一个小二叉树看待,其
顺序为BDF,读完这个,以A为根的三个结构就读完了根左,然后剩下CFG,这时在读CFG。到此为止,这组二叉树的前序组合为ABDRCFG,这种读法
从上往下,从根开始,把下面所有节点结构都以根左右的形式读取,遇到有子节点的情况变读左子节点,读完再读右。总结其格式:从根开始,找左,
以左为根,找左,若无,找右,以右为根,找左,若无,找右,若无,找上一级
右,以此类推。
中序:先把BDF,CFG看做是A的左右子节点,A1,A2。中序的读法为左根右,A1,A,A2。然后再看A1,D为左,B为中,E为右,D为叶节点
(无子节点了),因此从D开始DBE,A1读完,然后为A,再看A2,A2为FCG,因此中序的顺序为:DBE>A>FCG。
后序:左右根,A1,A2,A。A1在左右根:DEB,A2是FGC,A1,A2,A便是DEBFGCA。
按层遍历,其意义不大,就是按层来看,从上往下,从左往右,没错,就是ABCDEFG。
二叉树形式看似就是一种文件夹格式,其用处在于查找,插入数值和删除,在具体的,由于学的太渣,还未能说出来。。。


做一个生成二叉树的python文件

首先创建一个节点类,每次实例化出对象时,作为父节点的存在,默认值为#,存在两个子节点为None:
class Note(object):
    def __init__(self):
        self.data = '#'
        self.l_tree = None
        self.r_tree = None
接着创建tree类,继承于节点类:其中有方法为创建树结构:

class Tree(Note):#创建树类
    def create_tree(self,tree):#方法:创建树
        data = raw_input('->')#输入一个值data作为节点
        if data == '#':#当输入一个值为#时,树为空,不再创建子节点
            tree = None
        else:
            tree.data = data#当输入不为空时,树的节点值为data
            tree.l_tree = Note()#实例化左子节点
            self.create_tree(tree.l_tree)#左子节点调用创建树方法,创建下级左子树
            tree.r_tree = Note()#实例化右子节点
            self.create_tree(tree.r_tree)#右子节点调用创建树方法,创建下级右子树
当节点的子节点为空时,模型创建完毕,这时就可以按顺序print出其数据了
def print_all(self,tree):
    if tree.data != '#':#当节点值不是#时,打印节点
        print str(tree.data)+'\t',

在创建前序方法
def pre_tree(self,tree):#前序遍历
    if tree is not None:#从根节点寻找,当树不是空时
        self.print_all(tree)#打印根
        self.pre_tree(tree.l_tree)#打印左子树
        self.pre_tree(tree.r_tree)#打印右子树
    看到这是不是觉得它先只打印左节点,再打印右节点呢?仔细想想就会发现,从A开始后,进入到A1中,再以A1里B为起点,往下走,实
际上已经进入到了循环里。因此便打印出前序的二叉树结构。
    接下来再看中序和后序
 
    
def on_tree(self,tree):
    if tree is not None:
        self.on_tree(tree.l_tree)
        self.print_all(tree)
        self.on_tree(tree.r_tree)

def next_tree(self,tree):
    if tree is not None:
        self.next_tree(tree.l_tree)
        self.next_tree(tree.r_tree)
        self.print_all(tree)

同样的,只是根节点的顺序做了改变,将大体的结构看做根左右,每次都只读取最小的三小结构,这种顺序就避免了遍历出漏。
最后在附上运行该类的语句

if __name__ == '__main__':
    a = Tree()
    b = Note()
    a.create_tree(b)
    a.pre_tree(b)
    print '\n'
    a.on_tree(b)
    print '\n'
    a.next_tree(b)

你可能感兴趣的:(练习)