码迷,mamicode.com
首页 > 其他好文 > 详细

二叉树:树的创建和遍历

时间:2018-03-08 22:58:32      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:.com   不用   order   main   n+1   empty   style   技术分享   遍历   

前面介绍的链表,栈,队列都是一种顺序容器,访问元素的时候都是通过位置来访问的。如果想要通过值的方式来获取数据,只能通过遍历的方式。这在时间上消耗比较大。而二叉树可以做到不用遍历就可以通过值的方式来获取数据。二叉树是按值来保存元素,也按值来访问元素。

二叉树的相关术语:

树的结点:包含一个数据元素及若干指向子树的分支;

孩子结点:结点的子树的根称为该结点的孩子;

双亲结点:B 结点是A 结点的孩子,则A结点是B 结点的双亲;

兄弟结点:同一双亲的孩子结点; 堂兄结点:同一层上结点;

祖先结点: 从根到该结点的所经分支上的所有结点子孙结点:以某结点为根的子树中任一结点都称为该结点的子孙

结点层:根结点的层定义为1;根的孩子为第二层结点,依此类推;

树的深度:树中最大的结点层

结点的度:结点子树的个数

树的度: 树中最大的结点度。

叶子结点:也叫终端结点,是度为 0 的结点;

分枝结点:度不为0的结点;

有序树:子树有序的树,如:家族树;

无序树:不考虑子树的顺序;[3]  

二叉树的定义:

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

二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒。二叉树的第i层至多有2^(i-1)个结点;深度为k的二叉树至多有2^k-1个结点;对任何一棵二叉树T,如果其终端结点数为n_0,度为2的结点数为n_2,则n_0=n_2+1。

若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子节点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。

技术分享图片

一棵深度为k,且有2^k-1个节点的二叉树,称为满二叉树。

技术分享图片

这种树的特点是每一层上的节点数都是最大节点数。

而在一棵二叉树中,除最后一层外,若其余层都是满的,并且最后一层或者是满的,或者是在右边缺少连续若干节点,则此二叉树为完全二叉树。

技术分享图片

 

具有n个节点的完全二叉树的深度为log2n+1。深度为k的完全二叉树,至少有2^(k-1)个节点,至多有2^k-1个节点。

二叉树的性质:

性质1:二叉树第i层上的结点数目最多为 2{i-1} (i≥1)。
性质2:深度为k的二叉树至多有2{k}-1个结点(k≥1)。
性质3:包含n个结点的二叉树的高度至少为log2 (n+1)
性质4:在任意一棵二叉树中,若终端结点的个数为n0,度为2的结点数为n2,则n0=n2+1 

完全二叉树的性质:假设有n个节点

如果i=1,则结点i是二叉树的根

如果i>1,则其双亲结点是i/2

如果2i<=n,则结点的左孩子为2i

如果2i>n,则结点i无左孩子

如果2i+1<=n, 则结点i的右孩子为2i+1

如果2i+1>n,则结点i无右孩子。

技术分享图片

遍历二叉树:

有三种遍历方式:先根序遍历 中根序遍历 后根序遍历

先根序遍历:先访问根结点,而后以同样方式顺序遍历左子树和右子树

中根序遍历:先以同样方式遍历左子树,然后访问根结点,最后再以同样的方式遍历右子树

后根序遍历:先以同样方式遍历左右子树,最后访问根结点

比如下面这张图:

技术分享图片

先根序遍历的顺序 1->2->4->5->7->3->6

中根序遍历的顺序 4->2->7->5->1->3->6

后根序遍历的顺序 4->7->5->2->6->3->1

 

下面来看下如何创建二叉树和层次遍历一个二叉树

class Tree():

    def __init__(self):

        self.root=None

        self.result=[]

        self.q=[]

    def add(self,elem):

        node=Node(elem)

        if self.root is None:

            self.root=node

        else:

            q=[self.root]

            while True:

                pop_node=q.pop(0)

                if pop_node.lchild is None:

                    pop_node.lchild=node

                    return

                if pop_node.rchild is None:

                    pop_node.rchild = node

                    return

                else:

                    q.append(pop_node.lchild)

                    q.append(pop_node.rchild)

   #基于队列的层次遍历

    def level_print(self):

        if self.root == None:

            return ‘empyt tree‘

        self.q.append(self.root)

        while True:

            if len(self.q) > 0:

                current = self.q.pop(0)

                self.result.append(current.elem)

                if current.lchild != None:

                    self.q.append(current.lchild)

                if current.rchild != None:

                    self.q.append(current.rchild)

            else:

                break

        print self.result

 

if __name__=="__main__":

 

    elems=range(10)

    tree=Tree()

    for elem in elems:

        tree.add(elem)

tree.level_print()

打印结果:

/usr/bin/python2.7 /home/zhf/py_prj/data_struct/chapter6.py

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

 

先根遍历,中根遍历,后根遍历的实现

def pre_order(tree):

    if tree == None:

        return ‘empyt tree‘

    print tree.elem

    pre_order(tree.lchild)

    pre_order(tree.rchild)

 

 

def middle_order(tree):

    if tree == None:

        return ‘empty tree‘

    middle_order(tree.lchild)

    print tree.elem

    middle_order(tree.rchild)

 

def post_order(tree):

    if tree == None:

        return ‘empty tree‘

    post_order(tree.lchild)

    post_order(tree.rchild)

print tree.elem

运行结果:

/usr/bin/python2.7 /home/zhf/py_prj/data_struct/chapter6.py

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

pre_order

0

1

3

7

8

4

9

2

5

6

middle_order

7

3

8

1

9

4

0

5

2

6

post_order

7

8

3

9

4

1

5

6

2

0

 

二叉树:树的创建和遍历

标签:.com   不用   order   main   n+1   empty   style   技术分享   遍历   

原文地址:https://www.cnblogs.com/zhanghongfeng/p/8531097.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!