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

【数据结构】树与二叉树的基本概念

时间:2016-06-28 09:20:36      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:

1. 树的定义与抽象数据类型

(1) 树的定义

  树(Tree)是n(n>=0)个结点的有限集。n=0时称为空树。在任意一棵非空树中:

  1. 有且仅有一个特定的称为根(root)的结点;
  2. 当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1、T2、……、Tm,其中每一个集合本身又是一棵树,并且称为根的子树(subTree)。

  需要注意的是:

  • n>0时根结点是唯一的,不可能存在多个根结点,别和现实中的大树混为一起,现实中的树有很多根须,那是真实的树,数据结构中的树是只能有一个根结点;
  • m>0时,子树的个数是没有限制,但它们一定不相交。

(2) 树的抽象数据类型

ADT 树(Tree)
Data
  树是由一个根结点和若干棵子树组成。树中结点具有相同数据类型及层次关系。
Operation
  initTree(&T):构造空树T。
  destoryTree(&T):销毁树T。
  createTree(&T, definition):按definition中给出树的定义来构造树。
  clearTree(&T):若树T存在,则将树T清为空树。
  treeEmpty(T):若T为空树,返回true,否则返回false。
  treeDeep(T):返回T的深度。
  root(T):返回T的根结点。
  value(T, cur_e):cur_e是树T中的一个结点,返回此结点的值。
  assign(T, cur_e, value):给树T的结点cur_e赋值为value。
  parent(T, cur_e):若cur_e是树T的非根结点,则返回它的双亲,否则返回空。
  leftChild(T, cur_e):若cur_e是树T的非叶子结点,则返回它的最左孩子,否则返回空。
  rightSibling(T, cur_e):若cur_e有右兄弟,则返回它的右兄弟,否则返回空。
  insertChild(&T, &p, i, c):其中p指向树T的某个结点,i为所指结点p的度加上1,非空树c与T不相交,操作结果为插入c为树T中p指结点的第i棵子树。
  deleteChild(&T, &p, i):其中p指向树T的某个结点,i为所指结点p的度,操作结果为删除T中p所指结点的第i棵子树。
endADT

(3) 树的存储结构

双亲表示法

孩子表示法

孩子兄弟表示法

2. 二叉树的定义及性质

(1) 二叉树的定义

  二叉树(Binary Tree)是n(n >= 0)个结点的有限集合,该集合或者为空集(称为空二叉树),或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。

  特点:

  1. 每个结点最多有两棵子树,所以二叉树中不存在度大于2的结点。注意不是两棵子树,而是最多有。没有子树或者只有一棵子树都是可以有。
  2. 左子树和右子树是有顺序的,次序不能颠倒。
  3. 即使树中某结点只有一棵子树,也要区分它是左子树还是右子树。

  二叉树的五种基本形态:

  1. 空二叉树;
  2. 只有一个根结点;
  3. 根结点只有左子树;
  4. 根结点只有右子树;
  5. 根结点既有左子树,又有右子树。

(2) 一些特殊的二叉树

  斜树:

  顾名思义,斜树一定要是斜的,但是往哪斜还是有讲究的。所有的结点都只有左子树的二叉树叫左斜树。所有结点都是只有右子树的二叉树叫右斜树。这两者统称为斜树。

  满二叉树:

  在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有的叶子都在同一层上,这样的二叉树称为满二叉树。

  单是每个结点都存在左右子树,不能算是满二叉树,还必须要所有的叶子都在同一层上,这就做到了整棵树的平衡。因此,满二叉树的特点有:

  1. 叶子只能出现在最下一层;
  2. 非叶子结点的度一定是2;
  3. 在同样深度的二叉树中,满二叉树的结点个数最多,叶子数最多。

  完全二叉树:

  对一棵具有n个结点的二叉树按层序编号,如果编号为i(1 <= i <= n)的结点与同样深度的满二叉树中编号为i的结点在二叉树中位置完全相同,则这棵二叉树称为完全二叉树。

  完全二叉树的特点:

  1. 叶子结点只能出现在最下两层;
  2. 最下层的叶子一定集中在左部连续位置;
  3. 倒数第二层,若有叶子结点,一定都在右部连续位置;
  4. 如果结点度为1,则该结点只有左孩子,即不存在只有右子树的情况;
  5. 同样结点数的二叉树,完全二叉树的深度最小。

(3) 二叉树的性质

  性质1:在二叉树的第i层至多有2i-1个结点(i >= 1)。

  满二叉树每一层结点数最多,可以用归纳法得到结论。

  性质2:深度为k的二叉树至多有2k-1个结点(k >= 1)。

  由性质1可知:第1层最多1个结点,第2层最多2个结点,第3层最多3个结点,……,第k层至多2k-1个结点;

  则一共最多(1 + 2 + 4 + …… + 2k-1) = 2k-1 个结点。

  性质3:对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1。

  终端结点数其实就是叶子结点数,而一棵二叉树,除了叶子结点外,剩下的就是度为1或度为2的结点数了,我们设n1为度为1的结点数。则树T结点总数为n=n0+n1+n2

  则二叉树中总的入度数为n-1,因为除根结点外,每个结点入度均为1。

  二叉树中总的出度为n1+2n2,度为0的结点没有出度。

  显然二叉树中有 入度=出度,即n1+2n2=n-1=n0+n1+n2-1,则n0=n2+1。

  性质4:具有n个结点的完全二叉树的深度为[log2n]+1([x]表示不大于x的最大整数)。

  它的总结点数一定少于等于同样深度的满二叉树的结点数2k-1,但一定多于2k-1-1。

  即2k-1-1 < n <= 2k-1。

  也即2k-1 <= n < 2k

  两边取对数,可得到k-1 <= log2n < k

  而k作为深度数也是整数,因此,k=[log2n]+1。

  性质5:如果对一棵有n个结点的完全二叉树的结点按层序编号(从第1层到第[log2n]+1层,每层从左到右),对任一结点i(1<=i<=n)有:

  1. 如果i=1,则结点i是二叉树的根,无双新;如果i>1,则其双新结点为[i/2];

  2. 如果2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子结点是2i;

  3. 如果2i+1>n,是结点i无右孩子;否则其右孩子为2i+1。

(4) 二叉树的存储结构

  二叉树的顺序存储结构

  二叉树的顺序存储结构就是用一维数组存储二叉树中的结点,并且结点的存储位置,也就是数组的下标要能体现结点之间的关系,比如双亲与孩子的关系,左右兄弟的关系等。对于完全二叉树而言,层序编号即可反应逻辑关系。

  对于一般的二叉树,尽管层序编号不能反映逻辑关系,但可以将其按完全二叉树编号,只不过,把不存在的结点设置为空而已。

  考虑一种极端的情况,一棵深度为k的右斜树,它只有k个结点,却需要分配2k-1个存储单元空间,这显然是对存储空间的浪费,所以,顺序存储结构一般只用于完全二叉树。

  二叉链表

  二叉树的每个结点最多有两个孩子,所以为它设计一个数据域和两个指针域是比较自然的想法,我们称这样的链表叫做二叉链表。

  以下是我们的二叉链表的结点结构定义代码:

typedef struct BiTNode
{
    TElemType data; 
    struct BiTNode *lchild, *rchild; 
} BiTNode, *BiTree; 

  如果需要,还可以再增加一个指向其双亲的指针域,那样就称为三叉链表。

【数据结构】树与二叉树的基本概念

标签:

原文地址:http://www.cnblogs.com/xiaoxxmu/p/5599483.html

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