資料結構學習筆記-樹
阿新 • • 發佈:2018-12-20
樹
樹
基本概念:樹是結點的有限集
- 有且僅有一個特定的稱為根的結點
- 當時,其餘結點可分為m個互不相交的有限集,每個集合都是一棵樹,是根的子樹。
其他概念:
- 結點的度:子樹的個數;
- 樹的度:樹的節點中最大度
- 葉節點(終端結點):度為0的節點;而分支結點是度不為0的結點。
- 樹的深度:樹所有結點中最大層次(根節點的層次為1)
- 路徑長度:結點個數-1,或者說是分支條數
- 兄弟結點是父結點相同的結點
- 森林是棵互不相交的樹的集合
二叉樹
二叉樹是另一種樹形結構,每個結點至多隻有兩棵子樹,且有左右之分,需要注意的是,從樹的概念衍生來的二叉樹是可以為空樹的。
性質
- 在二叉樹的第層上至多有個結點(i>=1)
- 深度為的二叉樹至多有個結點(k>=1),由此,深度為且有個結點的二叉樹是滿二叉樹;而完全二叉樹是其個結點與滿二叉樹的個結點編號一致。
- 對任何一棵二叉樹T,若葉結點數為,度為2的結點數為,則。
- 對於完全二叉樹T,具有n個結點,其深度為
- 對於有個結點的完全二叉樹,i為結點編號,如果則是二叉樹的根,若則其雙親是(向下取整);另外,如果則無左孩子,則無右孩子
儲存結構
- 順序儲存,以陣列下標表示結點編號,明顯可以看出,如果樹不為完全二叉樹,則浪費了很多儲存空間
- 鏈式儲存 分為資料域和左右指標域,鏈的頭指標指向根節點,還有一種三叉連結串列,多加了一個指向雙親結點的指標。
二叉樹的遍歷和線索二叉樹
遍歷
- 前序遍歷 根結點-左子結點-右子結點
- 中序遍歷 左子結點-根結點-右子結點
- 後序遍歷 左子結點-右子結點-根結點 三種遍歷方式正好對應波蘭式,中綴表示式和逆波蘭式
bool PreOrderTraverse(BinTree T)
{
if (!T)
return 1;
else
{
Visit(T->data);
PreOrderTraverse(T->left);
PreOrderTraverse(T->right);
}
return 1;
}
遍歷演算法的不同之處僅僅為訪問結點的先後關係,其實遞迴執行過程是完全一樣的,仿照遞迴執行狀態中遞迴棧的變化可寫出相應的非遞迴演算法,若棧頂記錄的指標非空,則遍歷左子樹將左指標入棧;若棧頂記錄的指標為空,說明應當返回上一層,若從右子樹返回,不必儲存當前的根指標,直接修改指標即可。
bool InOrderTraverse(BinTree T)
{
InitStack(s);
BinTree p=T;
while(p||!isempty(s))
{
if(p)
{
Push(s,p);
p=p->left;
}
else
{
Pop(s,p);
if(!Visit(p->data))
return 0;
p=p->r;
}
}
return 1;
}
線索二叉樹
二叉連結串列作為儲存結構時,不能找到結點的前驅和後繼資訊,所以,將樹的空鏈域用來存放結點的前驅和後繼資訊。規定:如果結點有左子樹,則lchild域指示其左孩子,否則指示前驅,rchild域指示右孩子,否則指示後繼。為避免混淆,再增加兩個標誌域 這種結點結構組成的二叉連結串列作為二叉樹的儲存結構,叫做線索連結串列,指向前驅和後繼的指標稱為線索,樹也為線索二叉樹
- 中序線索二叉樹:樹中所有葉子結點的後繼由右鏈域指出。非葉子結點右鏈指向孩子,但是由中序遍歷可知,其後繼為遍歷該結點右子樹時的最左下端結點;同樣,找前驅時葉子結點左鏈域指向前驅,否則是該結點左子樹的最右下端結點
- 後序線索二叉樹:因為根節點在遍歷順序之後,所以根的後繼為空;若為右孩子或者左孩子(但沒有兄弟),則後繼結點就為根結點,若為左孩子且有右子樹,就是遍歷右子樹的第一個結點。