樹和二叉樹 -數據結構(C語言實現)


讀數據結構與算法分析

樹的概念

  • 一棵樹是一些節點的集合,可以為空
  • 由稱做根(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 ;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM