1. 程式人生 > >資料結構:三、樹結構概述

資料結構:三、樹結構概述

    在此文,我們將總結下資料結構中樹結構的主要知識點。

1、樹的定義

    樹(Tree)時n(n>=0)個結點的有限集,當n==0時稱為空樹,對於非空樹:

        (1)、有且僅有一個根結點;

        (2)、除去根結點,其餘結點可分為m(m>0)個互不相交的有限集,其中每個集合本身也是一棵樹,稱為根結點的子樹(SubTree)。(個人認為有一個特例:只有一個根結點的樹,它並沒有子樹,不具備非空樹的第二個定義,但課本里並沒有特別寫出這點)


    結點分類

    按照所處層次的不同,分為根結點、分支結點、葉結點


    結點間的關係

    按照所在的相對位置,有“子結點”、“父結點”、“兄弟結點”。

    上圖樹結構中,A是他們仨的父結點或雙親結點,反過來說,B、C、D三個結點便是A結點的子結點,BCD處於同一層,互稱為兄弟結點。

    結點的度

    結點的度是指該結點的子結點個數。上圖中根結點A的度為3,B結點的度為2,所有葉結點的度為0

    樹的度

    樹的度是指樹的各個結點的度的最大值。圖中樹的度為3。

    樹的深度

    從根結點開始為第一層,最大的層次數稱為數的深度 

    上圖中樹的深度為4。

    有序樹和無序樹
普通樹中的結點的左右子樹是可以互換的,稱為無序樹,而若將樹中結點的各子樹看成從左往右是有次序的,不能互換,則稱該樹為有序樹,如二叉樹便是一種有序樹。有序樹中最左邊的子樹的根稱為第一個孩子,最右邊的子樹的根稱為最後一個孩子。
    樹和森林

    森林是m(m>=0)棵互不相交的樹的集合。

ADT Tree{
InitTree(&T);//構造空樹
DestroyTree(&T);//銷燬樹T
CreateTree(&T, definition);//根據definition中給出的樹的定義來構造樹
ClearTree(&T);//若樹存在,則將樹T清空為空樹
TreeEmpty(T);//若樹為空樹,返回treu,否則返回false
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是樹的非葉結點,則返回它的最左孩子
RightSibling(T, cur_e);//若cur_e有右兄弟,則返回它的右兄弟否則返回空
InsettChild(&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棵子樹
TraverseTree(T);//按某種次序對T的每個結點訪問一次
}

2、二叉樹

    二叉樹與樹的主要區別:

    (1)、二叉樹每個結點至多隻有兩棵子樹,即不存在度大於2的結點;

    (2)、二叉樹的子樹有左右之分,其次序不能任意顛倒。

二叉樹的性質

1)、二叉樹的第i層上至多有2^(i-1)個結點;

2)、深度為k的二叉樹至多有2^k-1個結點;


下面介紹兩種比較特殊的二叉樹:滿二叉樹完全二叉樹

滿二叉樹:深度為k且含有(2^k)-1個結點的二叉樹。下圖為一棵深度為4的二叉樹。

    特點:每一層上的結點數都為最大結點數;可對滿二叉樹進行編號,自上而下,自左至右。


滿二叉樹

完全二叉樹:(課本官方定義)深度為k的,有n個結點的二叉樹,當且僅當其每一個結點都與深度為k的滿二叉樹中編號從1至n的結點一一對應時,稱該樹為完全二叉樹。個人比較庸俗不過比較容易理解的想法:深度為k的二叉樹,除了第k層的結點依次從左往右排列,前面k-1層結點組成滿二叉樹,則稱該二叉樹為完全二叉樹。如下圖為深度為4的完全二叉樹。

    特點:1)、葉結點只可能在層次最大的兩層上出現;

               2)、具有n個結點的完全二叉樹的深度為:log2n(向下取整)+1


完全二叉樹

在二叉樹的一些應用中,常會用到特殊的二叉樹——哈夫曼樹(即最優二叉樹)、線索二叉樹、平衡二叉樹等等,在之後會有篇專講這些二叉樹的,今天的課到這先告一段落啦。

    最後再附上二叉樹的基本操作

ADT BinaryTree{
InitBiTree(&T); //構造空二叉樹T
DestroyBiTree(&T);//銷燬二叉樹T
CreatBiTree(&T,definition);//按definition構造二叉樹T
ClearBiTree(&T);//將二叉樹清為空樹
BiTreeEmpty(T);//判斷T是否為空二叉樹,若是則返回true,不是返回false
BiTreeDepth(T);//返回T的深度
Root(T);//返回T的根
Value(T,e);//返回e的值
Assign(T,&e,value);//結點e賦值
Parent(T,e);//若e是T的非根結點,則返回它的雙親,否則返回“空”
LeftChild(T,e);//返回e的左孩子,若e無左孩子,則返回“空”
RightChild(T,e);//返回e的右孩子,若e無右孩子,則返回“空”
LeftSibling(T,e);//返回e的左兄弟,若e無左兄弟,則返回“空”
RightSibling(T,e);//返回e的右兄弟,若e無右兄弟,則返回“空”
InsertChild(&T,p,LR,c);//插入子樹,根據LR為0或1,插入c為T中p所指結點的左或右子樹。p所指結點的原有左或右子樹則成為c的右子樹
DeleteChild(&T,p,LR);//刪除子樹,根據LR為0或1,刪除T中p所指結點的左或右子樹
PreOrderTraverse(T);//先序遍歷T,對每個結點訪問一次
InOrderTraverse(T);//中序遍歷T,對每個結點訪問一次
PostOrderTraverse(T);//後序遍歷T,對每個結點訪問一次
LevelOrderTraverse(T);//層序遍歷T,對每個結點訪問一次
}