1. 程式人生 > >二叉樹模板 先中後序遍歷,非遞迴演算法,層次遍歷,葉子結點數,深度

二叉樹模板 先中後序遍歷,非遞迴演算法,層次遍歷,葉子結點數,深度

#include <iostream>
#include<stdio.h>
#include<malloc.h>
#include<queue>
#define MAX 50
using namespace std;
typedef struct BTNode        /*節點結構宣告*/
{
    char data ;               /*節點資料*/
    struct BTNode *lchild;
    struct BTNode *rchild ;  /*指標*/
}*BiTree;
int nodenum;
int leavesnum;

BiTree createBiTree(BiTree t)  /* 先序遍歷建立二叉樹*/
{
    char s;
    printf("\nplease input data:(exit for #)");
    s=getchar();
    if(s=='#')
    {
        t=NULL;
        return t;
    }
    t=(BiTree)malloc(sizeof(struct BTNode));
    if(t==NULL)
    {
        printf("Memory alloc failure!");
        return t;
    }
    t->data=s;
    nodenum++;                          /*二叉樹結點計數*/
    t->lchild=createBiTree(t->lchild); /*遞迴建立左子樹*/
    t->rchild=createBiTree(t->rchild); /*遞迴建立右子樹*/
    if(t->lchild==NULL&&t->rchild==NULL)
        leavesnum++;                    /*葉子結點計數*/
    return t;
}

void PreOrder(BiTree p)   /* 先序遍歷二叉樹*/
{
    if ( p!= NULL )
    {
        printf("%c", p->data);
        PreOrder( p->lchild ) ;
        PreOrder( p->rchild) ;
    }
}
void InOrder(BiTree p)   /* 中序遍歷二叉樹*/
{
    if( p!= NULL )
    {
        InOrder( p->lchild ) ;
        printf("%c", p->data);
        InOrder( p->rchild) ;
    }
}
void PostOrder(BiTree p)   /* 後序遍歷二叉樹*/
{
    if ( p!= NULL )
    {
        PostOrder( p->lchild ) ;
        PostOrder( p->rchild) ;
        printf("%c", p->data);
    }
}

void Preorder_n(BiTree p)  /*先序遍歷的非遞迴演算法*/
{
    BiTree stack[MAX],q;
    int top=0,i;
    for(i=0; i<MAX; i++)
        stack[i]=NULL; /*初始化棧*/
    q=p;
    while(q!=NULL)
    {
        printf("%c",q->data);
        if(q->rchild!=NULL)
            stack[top++]=q->rchild;
        if(q->lchild!=NULL)
            q=q->lchild;
        else if(top>0)
            q=stack[--top];
        else
            q=NULL;
    }
}

void InOrder_n(BiTree t)     /*中序遍歷二叉樹的非遞迴演算法*/
{
    BiTree stack[MAX],p;   /*定義順序棧stack,最大容量為100*/
    int top=0;               /*棧頂指標top*/
    p=t;
    do
    {
        while(p!=NULL)       /*順著左鏈走到盡頭*/
        {
            stack[top++]=p;  /*當二叉樹不空的時候根指標入棧*/
            p=p->lchild;     /*順著左鏈搜尋知道最左端葉子結點*/
        }
        if(top>0)
        {
            p=stack[top-1];                   /*棧不空時取出棧頂元素*/
            printf("%c",p->data);   /*輸出當前訪問的根結點*/
            top--;
            p=p->rchild;      /*順著右鏈搜尋*/
        }
    }
    while(top!=0||p!=NULL);  /*遍歷未結束時,繼續訪問結點*/
}

void PostOrder_n(BiTree t)  /*後序遍歷二叉樹的非遞迴演算法*/
{
    if(t==NULL)
        return ;
    BiTree stack[MAX],pnow=t,plast=NULL;          /*pnow當前訪問結點存根結點,plast上次訪問的結點,定義指標賦值NULL*/
    int top=0;                              /*棧頂充當指標作用的top*/
    while(pnow!=NULL)
    {
        stack[top++]=pnow;
        pnow=pnow->lchild;
    }                                           /*讓pnow指向最左下的結點的左孩子,值為NULL*/
    while(top>0)
    {
        pnow=stack[top-1];      /*讓pnow指向最左下的結點*/
        top--;                                 /*相當於棧頂元素出棧*/
        if(pnow->rchild==NULL||pnow->rchild==plast)         /*如果右子樹為空或右子樹已訪問過,訪問根結點*/
        {
            printf("%c",pnow->data);
            plast=pnow;                 /*plast存已訪問的最新結點*/
        }
        else                                    /*右子樹不為空且未訪問*/
        {
            stack[top++]=pnow;      /*左右根,要先輸出右,根結點再次進棧*/
            pnow=pnow->rchild;      /*當前訪問的結點更新為pnow的右子樹*/
            while(pnow!=NULL)
            {
                stack[top++]=pnow;
                pnow=pnow->lchild;
            }                                           /*找到該右子樹的最左下結點更新pnow*/
        }
    }
}

int TreeCount(BiTree t)         /*求二叉樹葉子結點數*/
{
    if(t==NULL)
        return 0;       /*空樹*/
    else if((t->lchild==NULL)&&(t->rchild==NULL))
        return 1;
    else
        return TreeCount(t->lchild)+TreeCount(t->rchild);
}

int Depth(BiTree t)     /*求二叉樹的深度*/
{
    int hl,hr;
    if(t==NULL)
        return 0;
    else
    {
        hl=Depth(t->lchild);
        hr=Depth(t->rchild);
        if(hl>=hr)
            return hl+1;
        else
            return hr+1;
    }
}

int TreeDepth(BiTree t)     /*求二叉樹的深度*/
{
    int rightdep=0;
    int leftdep=0;
    if(t==NULL)
        return 0;
    leftdep=TreeDepth(t->lchild);
    rightdep=TreeDepth(t->rchild);
    return (leftdep>rightdep)?(leftdep+1):(rightdep+1);
}

void release(BiTree t)  /*釋放二叉樹空間*/
{
    if(t!=NULL)
    {
        release(t->lchild);
        release(t->rchild);
        free(t);
    }
}

void LevelOrder(BiTree t)   /*層次遍歷*//*acm模板c++*/
{
    BiTree p=t;
    queue<BiTree>q;
    q.push(p);
    while(q.empty()!=1)
    {
        p=q.front();
        printf("%c",p->data);
        q.pop();
        if(p->lchild!=NULL)
            q.push(p->lchild);
        if(p->rchild!=NULL)
            q.push(p->rchild);
    }
}

int main()
{
    BiTree t=NULL;
    nodenum=0;
    leavesnum=0;
    t=createBiTree(t);
    printf("\n\nPreOrder the tree is:");
    PreOrder(t);
    printf("\n\nInOrder the tree is:");
    InOrder(t);
    printf("\n\nPostOrder the tree is:");
    PostOrder(t);
    printf("\n\n先序遍歷序列(非遞迴):");
    Preorder_n(t);
    printf("\n\n中序遍歷序列(非遞迴):");
    InOrder_n(t);
    printf("\n\n後序遍歷序列(非遞迴):");
    PostOrder_n(t);
    printf("\n\n層次遍歷序列:");
    LevelOrder(t);
    printf("\n\n二叉樹中結點總數:");
    printf("%d\n",nodenum);
    printf("\n\n二叉樹中葉子結點總數:");
    printf("%d\n",leavesnum);    /*或者TreeCount(t)*/
    printf("\n\n二叉樹的深度:");
    printf("%d\n",Depth(t));    /*或者TreeDepth(t)*/
    release(t);
    return 0;
}