二叉樹的三種遍歷的應用(表達式,求深度,葉子數,結點數,二叉樹的建立,復制)


表達式的表示

如圖所示的二叉樹表達式: a+b*(c-d)-e/f

若先序遍歷此二叉樹,按訪問結點的先后次序將結點排列起來,其先序序列為: (波蘭式,前綴表達式)  -+a*b-cd/ef

按中序遍歷,其中序序列為:a+b*c-d-e/f (中綴表達式)

按后序遍歷,其后序序列為:abcd-*+ef/- (逆波蘭式,后綴表達式)

注:人喜歡中綴形式的算術表達式,對於計算機,使用后綴易於求值

查詢二叉樹中某個結點

使用先序遍歷算法進行查詢遍歷

// 若二叉樹中存在和 x 相同的元素,則 p 指向該結點並返回 OK,否則返回 FALSE
bool Preorder (BiTree T, int x, BiNode *p)
{
    //如果二叉樹不為空,開始查詢結點
    if (T)
    {
        //如果根節點就是目標結點
        if (T->data == x)
        {
            //p 指向該結點並返回真
            p = T;
            
            return true;
        }
        else
        {
            //遞歸調用,也就是先序遍歷
            if (Preorder(T->lchild, x, p))
            {
               return true;
            }
            else
            {
                return(Preorder(T->rchild, x, p)) ;
            }
        }//end of else
    }//end of if
    else
    {
        return false;
    }
}

統計二叉樹中葉子結點的個數

還是先序遍歷的過程

//統計二叉樹中所有末位結點的個數,也就是葉子結點的個數的統計
void CountLeaf(BiTree T, int *count)
{
    //如果不為空樹
    if (T != NULL)
    {
        //如果樹的左右子樹都為空,那么葉子結點數+1
        if ((!T->lchild) && (!T->rchild))
        {
            // 對葉子結點計數
            count++;
        }
        //否則,繼續遞歸遍歷
        CountLeaf(T->lchild, count);
        CountLeaf(T->rchild, count);
    } // if
}

統計二叉樹中所有結點的個數

//返回指針T所指二叉樹中所有結點個數
//還是前序遍歷
int Count(BiTree T)
{
    //如果 T 為空
    if (!T)
    {
        //則說明是空樹,返回0個結點
        return 0;
    }
    //如果 T 的左右子樹 為空,說明只有一個結點,根節點而已
    if (!T->lchild && !T->rchild)
    {
       return 1;
    }
    else{
        //否則,遞歸遍歷
        int m = Count(T->lchild);
        int n = Count(T->rchild);
        
        return (m + n + 1);
    } //else
}

求二叉樹的深度(后序遍歷)

//求二叉樹的深度,后續遍歷的使用
int Depth(BiTree T)
{
    int depth;
    int depthLeft;
    int depthRight;
    //如果二叉樹為空
    if (!T)
    {
        depth = 0;
    }
    else
    {
        depthLeft = Depth(T->lchild);
        depthRight = Depth(T->rchild);
        depth = 1 + (depthLeft > depthRight ? depthLeft : depthRight);
    }
    
    return depth;
}

復制二叉樹(也是后序遍歷),其基本操作為:生成一個結點。

//生成一個二叉樹的結點,(其數據域為item,左指針域為lptr,右指針域為rptr)
BiNode * GetTreeNode(int item, BiNode *lptr, BiNode *rptr)
{
    BiTree T;
    //如果新建結點失敗
    if (!(T = new BiNode))
    {
        //退出
        exit(1);
    }
    //新建結點成功
    T->data = item;
    //
    T->lchild = lptr;
    T->rchild = rptr;
    //返回新建的結點的指針
    return T;
}

BiNode * CopyTree(BiNode *T)
{
    BiNode *newT;
    BiNode *newlptr;
    BiNode *newrptr;
    //如果源樹為空
    if (!T)
    {
        //返回空
       return NULL;
    }
    //如果根的左子樹不為空
    if (T->lchild)
    {
        newlptr = CopyTree(T->lchild); //復制左子樹
    }
    else
    {
        //左子樹為 null
        newlptr = NULL;
    }
    //如果根的右子樹不為空
    if (T->rchild)
    {
        newrptr = CopyTree(T->rchild); //復制右子樹
    }
    else
    {
        //否則,右子樹為 null
        newrptr = NULL;
    }
    //新生成一個二叉樹的結點,也就是后續遍歷的過程
    newT = GetTreeNode(T->data, newlptr, newrptr);
    
    return newT;
}

建立二叉樹的存儲結構,以遞歸方式建立二叉樹。

輸入結點值的順序必須對應二叉樹結點先序遍歷的順序。並約定以輸入序列中不可能出現的值作為空結點的值以結束遞歸。例如用“@”或用“-1”表示字符序列或正整數序列空結點。

如圖所示的二叉樹的先序遍歷順序為

A B C @ @ D E @ G @ @ F @ @ @

//遞歸建立二叉樹
bool CreateBiTree(BiTree T)
{
    char ch;
    //輸入結點的值
    scanf(&ch);
    //如果輸入空字符
    if(ch == ' ')
    {
        //代表空結點
        T = NULL;
    }
    else
    {
        T = (BiNode*)malloc(sizeof(BiNode));
        //如果新建結點失敗
        if (!T)
        {
             exit(1);
        }
        //成功。先序遍歷的順序建立二叉樹
        T->data = ch;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
    
    return true;
}

 

歡迎關注

dashuai的博客是終身學習踐行者,大廠程序員,且專注於工作經驗、學習筆記的分享和日常吐槽,包括但不限於互聯網行業,附帶分享一些PDF電子書,資料,幫忙內推,歡迎拍磚!

 


免責聲明!

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



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