讀數據結構與算法分析
樹的概念
- 一棵樹是一些節點的集合,可以為空
- 由稱做根(root)的節點以及0個或多個非空子樹組成,子樹都被一條來自根的有向邊相連
樹的實現
思路
孩子兄弟表示法:樹中的每個節點中除了數據為還有兩個指針,一個指向其兒子,一個指向其兄弟。
樹的節點聲明
typedef struct TreeNode *PrtToNode ;
struct TreeNode
{
ElementType Element ;
PrtToNode FirstChild ;
PrtToNode NextSibling ;
}
樹的遍歷
先序遍歷
以打印文件目錄為例
void ListDir(DirectoryOrFile D,int Depth) //傳進第一個目錄和深度(第幾級)
{
if( D 是一個合法的文件目錄)
{
PrintName(D,Depth) ;//先序遍歷,即先訪問它的名字打印出來
for(遍歷 D 所有的孩子 C)
ListDir(C,Depth + 1) ; //遞歸調用,遍歷子樹
}
}
void ListDirectory(DirectoryOrFile D) //啟動程序
{
ListDir(D,0) ;
}
后序遍歷
以計算文件目錄大小為例
void SizeDirectory(DirectoryOrFile D)
{
int TotalSize ;
TotalSize = 0 ;
if(D 是一個合法的文件目錄)
{
TotalSize = FileSize(D) ;
for(D 的每個孩子 C)
TotalSize += SizeDirectory(C) ;
}
return TotalSize ;
}
二叉樹
是一顆每個節點都不能由多於兩個兒子的樹
實現
二叉查找樹:左子樹關鍵字小於父節點,右子樹關鍵字大於父節點
節點聲明和初始化
struct TreeNode ;
typedef struct TreeNode *Poisition ;
typedef struct TreeNode *SearchTree ;
SearchTree MakeEmpty(SearchTree T) ;
Position Find(ElementType X, SearchTree T) ;
Position FindMin(SearchTree T) ;
Position FinMax(SearchTree T) ;
SearchTree Insert(ElementType X, SearchTree T) ;
SearchTree Delete(ElementType X, SearchTree T) ;
ElementType Retrieve(Poisition P) ;
struct TreeNode
{
ElementType Element ;
PtrToNode Left ;
PtrToNode Right ;
}
Find操作
Position Find(ElementType X, SearchTree T)
{
if(T == NULL)
return NULL ;
else if(X < T->Elements)
return Find(X,T->Left) ;
else if(X > T->Elements)
return Find(X,T->Right) ;
return T ;
}
FindMin和FindMax操作
遞歸和非遞歸實現
Position FindMin(SearchTree T)
{
if(T == NULL)
return NULL ;
else if(T->Left == NULL)
return T ;
else
return FindMin(T->Left) ;
}
Position FindMax(SearchTree T)
{
if(T != NULL)
while(T->Right != NULL)
T = T->Right ;
return T;
}
Insert操作
SearchTree Inesert(ElementType X, SearchTree T)
{
if(T == NULL)
{
T = malloc(sizeof(struct
TreeNode)) ;
if(T == NULL)
FatalError("內存不足") ;
T->Element = X ;
T->Left = T->Right = NULL;
}
else if(X < T->Element)
T-Left = Insert(X,T->Left) ;
else if(X > T->Element)
T-Right = Insert(X,T->Right) ;
return T ;
}
Delete操作
只有一個節點的情況,直接用子樹頂替
由兩個節點的情況,找到右子樹最小的元素頂替它,並刪除這顆樹(這顆樹肯定只有一個節點)
SearchTree Delete(Element X, SearchTree T)
{
Position TmpCell ;
if(T == NULL)
Error("未找到") ;
else if(X < T->Element)
T->left = Delete(X,T-Left) ;
else if(X > T->Element)
T->Right = Delete(X,T->Right) ;
else if(T->Left && T->Right)
{
TmpCell = FindMin(T->Right) ;
T->Element = TmpCell->Element ;
T->Right = Delete(TmpCell->Element,T->Right) ;
}
else
{
TmpCell = T ;
if(T->Left == NULL)
T = T->Right ;
if(T->Right == NULL)
T = T ->Left ;
free(TmpCell) ;
}
return T ;
}
