数据结构笔记5 树与树的表示

(笔记总结自浙江大学数据结构)

文章目录

    • 引子(顺序查找、二分查找)
    • 树的定义
    • 树的一些基本术语
    • 树的表示

引子(顺序查找、二分查找)

分层次组织在管理上具有更高的效率。
查找是数据管理的基本操作之一,那么如何实现有效率的查找?

查找:根据某个给定关键字K ,从集合R中找出关键字与K相同的记录。
静态查找:集合中记录是固定的。没有插入和删除操作,只有查找。
动态查找:集合中记录是动态变化的。除查找,还可能发生插入和删除。

静态查找
方法1:顺序查找

int SequentialSearch (StaticTable *Tbl, 
 ElementType K)
{ /*在表Tbl[1]~Tbl[n]中查找关键字为K的数据元素*/
 int i;
 Tbl->Element[0] = K; /*建立哨兵*/
 for(i = Tbl->Length; Tbl->Element[i]!= K; i--);
 return i; /*查找成功返回所在单元下标;不成功返回0*/
}

顺序查找算法的时间复杂度为O(n)。

方法2:二分查找(Binary Search)
假设n个数据元素的关键字满足有序(比如:小到大)并且是连续存放(数组),那么可以进行二分查找。

int BinarySearch ( StaticTable * Tbl, ElementType K)
{ /*在表Tbl中查找关键字为K的数据元素*/
 int left, right, mid, NoFound=-1;
 left = 1; /*初始左边界*/
 right = Tbl->Length; /*初始右边界*/
 while ( left <= right )
 {
 mid = (left+right)/2; /*计算中间元素坐标*/
 if( K < Tbl->Element[mid]) right = mid-1; /*调整右边界*/
 else if( K > Tbl->Element[mid]) left = mid+1; /*调整左边界*/
 else return mid; /*查找成功,返回数据元素的下标*/
 }
 return NotFound; /*查找不成功,返回-1*/
}

二分查找算法具有对数的时间复杂度O(logN)。

判定树上每个结点需要的查找次数刚好为该结点所在的层数
查找成功时查找次数不会超过判定树的深度
n个结点的判定树的深度为[log2n]+1.
ASL = (44+43+2*2+1)/11 = 3(平均查找长度)

树的定义

(Tree): n(n≥0)个结点构成的有限集合。
当n=0时,称为空树
对于任一棵非空树(n> 0),它具备以下性质:
树中有一个称为“(Root)”的特殊结点,用 r 表示;
其余结点可分为m(m>0)个互不相交的有限集T1,T2,… ,Tm,其中每个集合本身又是一棵树,称为原来树的“子树(SubTree)”

子树是不相交的;
除了根结点外,每个结点有且仅有一个父结点
一棵N个结点的树有N-1条边
(树是保证结点连通的最小的一种连接方式。)

问:有一个m棵树的集合(也叫森林)共有k条边,问这m颗树共有多少个结点?
答:k+m

树的一些基本术语

  1. 结点的度(Degree):结点的子树个数
  2. 树的度:树的所有结点中最大的度数
  3. 叶结点(Leaf):度为0的结点
  4. 父结点(Parent):有子树的结点是其子树的根结点的父结点
  5. 子结点(Child):若A结点是B结点的父结点,则称B结点是A结点的子结点;子结点也称孩子结点
  6. 兄弟结点(Sibling):具有同一父结点的各结点彼此是兄弟结点。
  7. 路径和路径长度:从结点n1到nk的路径为一个结点序列n1 , n2,… , nk, ni是 ni+1的父结点。路径所包含边的个数为路径的长度。
  8. 祖先结点(Ancestor):沿树根到某一结点路径上的所有结点都是这个结点的祖先结点。
  9. 子孙结点(Descendant):某一结点的子树中的所有结点是这个结点的子孙。
  10. 结点的层次(Level):规定根结点在1层,其它任一结点的层数是其父结点的层数加1。
  11. 树的深度(Depth):树中所有结点中的最大层次是这棵树的深度。

树的表示

儿子-兄弟表示法
数据结构笔记5 树与树的表示_第1张图片
数据结构笔记5 树与树的表示_第2张图片

typedef struct TNode *Position;
typedef Position BinTree; /* 二叉树类型 */
struct TNode{ /* 树结点定义 */
    ElementType Data; /* 结点数据 */
    BinTree Left;     /* 指向左子树 */
    BinTree Right;    /* 指向右子树 */
};

在用“儿子-兄弟”法表示的树中,如果从根结点开始访问其“次子”的“次子”,所经过的结点数与下面哪种情况一样?(注意:比较的是结点数,而不是路径)(C)
A.从根结点开始访问其“长子”的“长子”
B.从根结点开始访问其“长子”的“长子”的“长子”
C.从根结点开始访问其“长子”的“长子”的“长子”的“长子”
D.不能确定,要看具体树结构
(访问到次子:两个节点,再到次子的次子,又是两个节点。共4个节点。
A:长子的长子,两个节点。
B:三个节点。
C:四个节点。)

一棵度为m的树有n个节点。若每个节点直接用m个链指向相应的儿子,则表示这个树所需要的总空间是n*(m+1) (假定每个链以及表示节点的数据域都是一个单位空间).。当采用儿子/兄弟(First Child/Next Sibling)表示法时,所需的总空间是:(A)
A.3n
B.2n
C.nm
D.n
(m-1)
(因为每个节点都得需要m个链来指向相应的儿子,再加上一共有n个节点,故一共有n*(m+1)个子节点。
现在考虑儿子/兄弟表示法,把n个节点串联起来,因为每个节点都有两个部分组成,一个是指向下一个兄弟节点,一个是指向子节点,所以在树中,这两个部分都是需要作为一个单位(即链)来存储的,加上n个节点本身,一共需要3n个空间。)

你可能感兴趣的:(数据结构)