数据结构(三):非线性逻辑结构-树

经过数据结构(二)系列文章,已经把线性结构中最常用的数据结构进行了介绍,包括顺序存储结构中顺序表、顺序队列和顺序栈,链式存储结构中的链表、链栈和链队列。线性结构是数据结构中最为常见也最简单的逻辑结构。下面将进入非线性逻辑的数据结构部分,还记得下面的一副数据结构的分类图吧,对于非线性逻辑,主要介绍树和图。本文主要先针对树进行复习和总结,后续的博文将逐渐深入到图等更为复杂的非线性逻辑数据结构。


树的总论

树的直观示意图


树的定义

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

树的特点

树中至少有一个结点——根(root);

树中各子树是互不相交的集合。


基本概念和术语

结点(node)——表示树中的元素
结点的度(degree)——结点拥有的子树数
叶子(leaf)——度为0的结点
孩子(child)——结点子树的根称为该结点的孩子
双亲(parents)——孩子结点的上层结点叫该结点的~
兄弟(sibling)——同一双亲的孩子
树的度——一棵树中最大的结点度数
结点的层次(level) ——从根结点算起,根为第一层,它的孩子为第二层……
深度(depth)——树中结点的最大层次数
森林(forest) ——m(m>0)棵互不相交的树的集合

路径:根节点到某节点之间;两节点之间;路径是唯一的
路径的长度
结点的深度 (depth),高度(height)
树的深度,高度
结点的祖先
结点后代

树的种类

有向树:(1) 有确定的根;(2) 树根和子树根之间为有向关系

有序树:子树之间存在确定的次序关系

无序树:子树之间不存在确定的次序关系

下面通过一个例子来充分理解上面提到的那些概念和术语:


树的表示

如下图所示


深林

是m(m≥0)棵互不相交的树的集合。如图所示,任何一棵非空树是一个二元组,Tree = (root,F),其中:root 被称为根结点,F 被称为子树森林


树与线性结构的比较

线性结构:第一个数据元素(无前驱);最后一个数据元素(无后继);其它数据元素(一个前驱、一个后继)

树型结构:根结点(无前驱);多个叶子结点(无后继);其它数据元素(一个前驱、多个后继)。

二叉树

或为空树;或是由一个根结点加上两棵分别称为左子树和右子树的、互不交的二叉树组成。二叉树的五种基本形态如图所示


二叉树的性质

性质 1 :在二叉树的第 i层上至多有2i-1 个结点。 (i≥1)可用归纳法证明
性质 2 :深度为 k 的二叉树上至多含2k-1 个结点(k≥1)
性质 3 :对任何一棵二叉树,若它含有n0叶子结点n2 个度为 2的结点,则必存在关系式:n0=n2+1
证明:
设二叉树上结点总数 n = n0+n1+n2
二叉树上分支总数 b = n1+2n2
b = n-1 = n0+n1+n2-1

两类特殊的二叉树

满二叉树:指的是深度为k且含有2k-1个结点的二叉树。
完全二叉树:树中所含的 n 个结点和满二叉树中编号为 1 至 n 的结点一一对应


性质 4 :具有 n 个结点的完全二叉树的深度为d,则满足关系式:n = 2d-1
性质 5 :若对含 n 个结点的完全二叉树从上到下且从左至右进行 1至 n的编号,则对完全二叉树中任意一个编号为 i的结点:
(1) 若 i=1,则该结点是二叉树的根,无双亲, 否则编号i/2的结点为双亲结点
(2)若 2i>n,则该结点无左孩子否则,编号为 2i 的结点为其左孩子结点;
(3) 若 2i+1>n,则该结点无右孩子结点,否则,编号为2i+1 的结点为其右孩子结点。

二叉树的存储结构

二叉树的顺序存储表示

实现:按满二叉树的结点层次编号,依次存放二叉树中的数据元素
特点:结点间关系蕴含在其存储位置中浪费空间,适于存满二叉树和完全二叉树


建立二叉树的顺序存储结构

voidMakeSeqBTree(SeqList *L)

{

   char ch;

   ch=getchar();

   while(ch!=‘ ’)

    {  if(ch!=‘ ‘)

          InsertRear(L,ch);

          ch=getchar();

    }

}


数组下标i和二叉树层次间的关系
i>0,data[(i-1)/2]不是虚结点就是i的双亲,i=0是根
如果2i+1<L->size,data[2i+1]不是虚结点就是左孩子;2i+1>L->size,data[i]是叶子
如果2i+2<L->size,data[2i+2]不是虚结点就是右孩子;2i+2>L->size,data[i]无右孩子
i是偶数且>0,data[i-1]不是虚结点就是data[i]的左兄弟
如果i<L->size且是奇数,data[i+1]不是虚结点就是data[i]的右兄弟


顺序存储结构:

孩子表示法


应用范围:适用于二叉树上的结点个数已知,或不支持动态存储分配的高级语言

双亲表示法

实现:定义结构数组存放树的结点,每个结点含两个域:
            数据域:存放结点本身信息
            双亲域:指示本结点的双亲结点在数组中位置
特点:找双亲容易,找孩子难

二叉树的链式存储表示

二叉链表
三叉链表

二叉树的建立

二叉树的建立是指在内存中建立二叉树存储结构。
二叉树的顺序存储结构的建立比较简单,只需将二叉树各个结点的信息(值)按原有的逻辑关系送入相应的向量单元中即可。
二叉树链式存储结构的建立算法有多种。
   按完全二叉树的层次顺序,依次输入结点信息建立二叉链表的算法。对于一般的二叉树,必须添加若干个虚结点使其成为完全二叉树。

由顺序表建立二叉树算法的基本思想

1。初始,顺序表中的第一个元素建立根结点,并将根指针入队
2。对顺序表的元素顺序扫描,如果不是虚结点,其结点指针恰是队头元素,则删除队头;如果该元素在表中有左右孩子,则建立左右孩子并与出队结点连接,孩子结点入队。

*******************************************************************************************************************************************************************************************************

2015-7-29

原文地址:https://www.cnblogs.com/huty/p/8519291.html