資料結構實驗——二叉樹的常見操作

life4711發表於2014-11-08

要求:

⑴輸入字元序列,建立二叉連結串列。

⑵中序遍歷二叉樹:遞迴演算法。

⑶中序遍歷二叉樹:非遞迴演算法。(最好也能實現先序,後序非遞迴演算法)

⑷求二叉樹的高度。

⑸求二叉樹的葉子個數。

*⑹將二叉連結串列視為森林的孩子兄弟連結串列,計算森林中葉子個數。

*⑺建立中序線索二叉樹,並實現中序遍歷。

⑻藉助佇列實現二叉樹的層次遍歷。 

⑼在主函式中設計一個簡單的選單,分別除錯上述演算法。

#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
#define NULL 0
#define N 10
typedef int ELEMTP;
typedef struct node
{
    ELEMTP data;
    struct node *lchild,*rchild;
} TNode;
//建立二叉樹
TNode * create_tree()
{
    TNode *t;
    ELEMTP x;
    cin>>x;
    if(x!=0)
    {
        t=new TNode;
        t->data=x;
        t->lchild=create_tree();
        t->rchild=create_tree();
    }
    else
        t=NULL;
    return t;
}
//建立二叉樹的另一種方法
void create_tree1(TNode **t)
{
    ELEMTP x;
    cin>>x;
    if(x==0)
        *t=NULL;
    else
    {
        *t=new TNode;
        (*t)->data=x;
        create_tree1(&((*t)->lchild));
        create_tree1(&((*t)->rchild));
    }

}
//遞迴先序遍歷二叉樹
void preorder(TNode *t)
{
    if(t)
    {
        cout<<t->data<<"      ";
        preorder(t->lchild);
        preorder(t->rchild);
    }
}
// 遞迴中序遍歷二叉樹
void inorder(TNode *t)
{
    if(t)
    {
        inorder(t->lchild);
        cout<<t->data<<"      ";
        inorder(t->rchild);
    }
}
//遞迴後序遍歷二叉樹
void pasorder(TNode *t)
{
    if(t)
    {
        pasorder(t->lchild);
        pasorder(t->rchild);
        cout<<t->data<<"      ";
    }
}
//遞迴演算法求二叉樹葉子結點數
void count_leaf(TNode *t,int *n)
{
    if(t)
    {
        if(t->lchild==NULL && t->rchild==NULL)
            (*n)++;
        count_leaf(t->lchild,n);
        count_leaf(t->rchild,n);
    }
}
//遞迴演算法求二叉樹的高度
int hight_bit(TNode *t)
{
    int l,h;
    if(t)
    {
        l=hight_bit(t->lchild);
        h=hight_bit(t->rchild);
        if(l>h)
            return l+1;
        else
            return h+1;
    }
    else
        return 0;
}
//遞迴演算法將二叉樹的左右子數交換
void exchange(TNode **t)
{
    TNode *p;
    if(*t)
    {
        exchange(&((*t)->lchild));
        exchange(&((*t)->rchild));
        p=(*t)->lchild;
        (*t)->lchild=(*t)->rchild;
        (*t)->rchild=p;
    }
}


//非遞迴先序遍歷演算法
void preorder1(TNode *t)
{
    TNode * s[N],*p;
    int top;
    top=0;
    p=t;
    while(p || top>0)
    {
        while(p)
        {
            cout<<p->data<<"      ";
            top++;
            s[top]=p;
            p=p->lchild;
        }
        if(top>0)
        {
            p=s[top];
            --top;
            p=p->rchild;
        }
    }
}
//二叉樹中序非遞迴演算法
void inorder1(TNode *t)
{
    TNode *p,*s[N];
    int top;
    top=0;
    p=t;
    while(p || top>0)
    {
        while(p)
        {
            top++;
            s[top]=p;
            p=p->lchild;
        }
        if(top>0)
        {
            p=s[top];
            top--;
            cout<<p->data<<"      ";
            p=p->rchild;
        }
    }
}
//二叉樹後根非遞迴演算法
void pasorder1(TNode *t)
{
    struct
    {
        TNode *pp;
        int tag;
    } ss[N];
    int top;
    TNode *p;
    top=0;
    p=t;
    while(p || top>0)
    {
        while(p)
        {
            top++;
            ss[top].tag=0;
            ss[top].pp=p;
            p=p->lchild;
        }
        if(top>0)
            if(ss[top].tag==0)
            {
                ss[top].tag=1;
                p=ss[top].pp;
                p=p->rchild;
            }
            else
            {
                p=ss[top].pp;
                cout<<p->data<<"      ";
                top--;
                p=NULL;
            }
    }
}
//非遞迴先序方法求二叉數葉子結點數
void count_leaf1(TNode *t,int *n)
{
    TNode *s[N],*p;
    int top;
    top=0;
    p=t;
    while(p || top>0)
    {
        if(p)
        {
            if(p->lchild==NULL && p->rchild==NULL)
                (*n)++;
            top++;
            s[top]=p;
            p=p->lchild;
        }
        else
        {
            p=s[top];
            top--;
            p=p->rchild;
        }
    }
}
//非遞迴中序求二叉樹葉子結點數
int count_leaf2(TNode *t)
{
    int n,top;
    TNode *s[N],*p;
    n=0;
    top=0;
    p=t;
    while(p || top>0)
    {
        while(p)
        {
            top++;
            s[top]=p;
            p=p->lchild;
        }
        p=s[top];
        top--;
        if(p->lchild==NULL && p->rchild==NULL)
            n++;
        p=p->rchild;
    }
    return n;
}
//非遞迴後序求二叉樹葉子結點數
int count_leaf3(TNode *t)
{
    struct
    {
        TNode *pp;
        int tag;
    } s[N],ss;
    int top,n;
    TNode *p;
    top=0;
    n=0;
    p=t;
    while(p || top>0)
    {
        while(p)
        {
            top++;
            s[top].pp=p;
            s[top].tag=0;
            p=p->lchild;
        }
        ss=s[top];
        top--;
        if(ss.tag==0)
        {
            ss.tag=1;
            top++;
            s[top]=ss;
            p=ss.pp->rchild;
        }
        else
        {
            p=ss.pp;
            if(p->lchild==NULL && p->rchild==NULL)
                n++;
            p=NULL;
        }
    }
    return n;
}
//求給定結點的所有祖先和祖先數
int count_zx(TNode *t,ELEMTP x)
{
    struct
    {
        TNode *pp;
        int tag;
    } s[N],ss;
    int top,n;
    TNode *p;
    top=0;
    n=0;
    p=t;
    while( p || top>0)
    {
        while(p)
        {
            top++;
            s[top].pp=p;
            s[top].tag=0;
            p=p->lchild;
        }
        ss=s[top];
        top--;
        if(ss.tag==0)
        {
            ss.tag=1;
            top++;
            s[top]=ss;
            p=ss.pp->rchild;
        }
        else
        {
            if(ss.pp->data==x)
                break;
            p=NULL;
        }
    }
    cout<<"the zx wei:"<<endl;
    for(n=1; n<=top; n++)
    {
        p=s[n].pp;
        cout<<p->data<<"   ";
    }
    return top;
}
//非遞迴演算法求二叉樹的高度演算法
int hight_bit1(TNode *t)
{
    TNode * s[N];
    ELEMTP node[N];//儲存葉子結點
    int top,i,j,h,n;
    TNode *p;
    top=0;
    n=0;
    p=t;
    while(p || top>0)
    {
        if(p)
        {
            if(p->lchild==NULL && p->rchild==NULL)
                node[n++]=p->data;
            top++;
            s[top]=p;
            p=p->lchild;
        }
        else
        {
            p=s[top];
            top--;
            p=p->rchild;
        }
    }
    cout<<"the leaf is:";
    for(i=0; i<n; i++)
        cout<<node[i];
    h=-32767;
    for(i=0; i<n; i++)
        if(h<count_zx(t,node[i])) //求所在葉結點的祖先數
            h= count_zx(t,node[i])+1;
    return h+1;
}

int  main()
{
    TNode *t;
    int num;
// t=create_tree();
    create_tree1(&t);
    preorder(t);
    cout<<endl;
//  preorder1(t);
//  cout<<endl;
//  inorder(t);
//  cout<<endl;
//  inorder1(t);
//  cout<<endl;
//  pasorder(t);
// cout<<endl;
//  pasorder1(t);
//    cout<<endl;
    num=0;
// count_leaf(t,&num);
// count_leaf1(t,&num);
//num=count_leaf2(t);
    num=count_leaf3(t);
    cout<<"the binary tree's leaf is:"<<num<<"個";
    cout<<endl;
//求給定結點的所有祖先和祖先數
    num=count_zx(t,6);
    cout<<endl<<num;
    cout<<endl;
//遞迴演算法求二叉樹的高度
//num= hight_bit(t);
//cout<<"the binary tree's hight is:"<<num;
//cout<<endl;
//num=hight_bit1(t);
// cout<<"the hight is:"<<num;
//遞迴演算法將二叉樹的左右子數交換
// exchange(&t);
// cout<<endl;
// preorder(t);
   return 0;
}







 

作者:王老師

(Yran有改動)
 

相關文章