二叉树的基本性质、存储方式与遍历(Python实现)

来源:互联网 发布:执行仪表板软件 编辑:程序博客网 时间:2024/05/24 23:12

二叉树

二叉树(Binary Tree)是树的一种特殊形式,也就是每个节点之下最多拥有2个孩子,相应地若最多不超过M个孩子,那就成为M叉树,但实际上我们统称为多叉树。对于二叉树,常用的定理有四条:

  • 深度为i的二叉树最多含有2i1 个节点;
  • 第i层至多有2i1个节点;
  • 对于任意一颗二叉树,若其终端节点数为n0,度为2的节点数为n2,则n0=n2+1。证明如下:

    1n=n0+n1+n2
    2n=B+1B
    3B=n1+2n2
    由上述三式即可得出此定理。

  • 对于一棵完全二叉树(除最后一层外每一层都为满二叉树)而言,其叶子节点数具有以下关系:
    n0=n2nn+12n


二叉树的存储

在将二叉树的存储之前,我们先了解一下树的存储方式,常用输的存储方式有三种,在介绍之前,我们先把树的例子放出来,再来看各种存储方式的不同。
这里写图片描述

  • 双亲表示法
    所谓双亲表示法就是会设置一个指示器来指向其双亲所在的位置。那么我最终应当会存储为一个如下的数组:
    这里写图片描述
    • 优点:Parent(T,x)可以很快找到双亲
    • 缺点:求节点的孩子时就必须遍历整个结构
  • 孩子表示法
    所谓孩子表示法就是会在数据后面存储其孩子节点,但也有两种方式:
    • 方法一:
      这里写图片描述
      但是这样的方法比较浪费空间,因为你并不知道多叉树中每个节点一共有多少个孩子节点,而不存在的节点,也必须进行保存为null;
    • 方法二:
      这里写图片描述
      这样的方法相对于第一种加入了degree的值,可以更节省空间,但是对树进行插入或删除等的操作的时候却增加了复杂度。
  • 孩子兄弟表示法
    孩子兄弟表示法也是二叉树的一种表示方法,数据的两端分别存放其左节点的孩子和其兄弟节点。
    这里写图片描述

其数据结构也可以很方便的定义:

typedef struct CSNode{ElementType data;Struct      CSNode *firstchild,*nextsibling;} CSNode,*CSTree;

二叉树的遍历

所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问题。
 遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础。
 从二叉树的递归定义可知,一棵非空的二叉树由根结点及左、右子树这三个基本部分组成。因此,在任一给定结点上,可以按某种次序执行三个操作:
 (1)访问结点本身(N),
 (2)遍历该结点的左子树(L),
 (3)遍历该结点的右子树(R)。

在访问时要求必须先访问左子树再访问右子树,按照对根节点的访问顺序,二叉树的遍历分为三种:先序中序和后序遍历。
我们还是以刚才的二叉树作为例子,那么

  • 先序遍历的结果应该为:RACDBEF
  • 中序遍历的结果应该为:CADREBF
  • 后序遍历的结果应该为:CDAEFBR

用二叉链表做为存储结构,中序遍历算法可描述为:

 void InOrder(BinTree T)        {          if(T) { // 如果二叉树非空              InOrder(T->lchild);              printf("%c",T->data); // 访问结点              InOrder(T->rchild);            }           } // InOrder

代码实现

#! /usr/bin/env python                                                           # -*-coding:utf-8 -*-                                                            # Fuction: Create a binary search tree and tranversal in different way           # Coder: Memory                                                                  # Date: 2015-04-18                                                               class treeNode():     def __init__(self, data, left, right):                                               self.data = data                                                                    self.left = left                                                                    self.right = right class BTree:                                                                            def __init__(self):                                                                     self.root = None                                                                def is_empty(self):                                                                     if self.root is None:                                                                   return True                                                                  else:                                                                                return False                                                             def insert(self, data):                                                              r = self.root                                                                    if r is None:                                                                        self.root = treeNode(data, None, None)                                              return                                                                          while True:                                                                             # 比根结点小放在左边                                                                if r.data > data:                                                                       if r.left is None:                                                                      r.left = treeNode(data, None, None)                                                 break                                                                           else:                                                                                   r = r.left                                                                  else:                                                                                   # 比根结点大放在右边                                                                if r.right is None:                                                                     r.right = treeNode(data, None, None)                                                break                                                                           else:                                                                                   r = r.right                                                         def traversal(self, root):                                                              if root is None:                                                                        return                                                                          else:                                                                                   # 先序遍历                                                                          print root.data                                                                    self.traversal(root.left)                # 中序遍历去掉下一行的注释            # print root.data                                                       self.traversal(root.right)                                                      # 后序遍历同上        # print root.dataif __name__ == '__main__':                                                              bt = BTree()                                          bt.insert(10)                                                                    bt.insert(3)                                                                     bt.insert(12)                                                                    bt.insert(6)                                                                     bt.insert(24)                                                                    bt.insert(30)                                                                    bt.insert(1)                                                                     bt.insert(5)      # 若用户输入的是数组,就一个个一个地输入就好了。                                                                   bt.traversal(bt.root)                                                        

二叉树的应用和衍生有很多,比如:哈夫曼树(最优二叉树),二叉搜索树等等。将在后续的博文中一一介绍。

0 0
原创粉丝点击