數據結構與算法實驗 實驗6:二叉樹ADT的二叉鏈式實現 (由完全前序序列創建二叉樹 / 求二叉樹的節點數/樹高/葉子節點數 /先序中序後序層序遍歷)

假設二叉數的數據元素爲字符,採用二叉鏈式存儲結構。請編碼實現二叉樹ADT,其中包括創建二叉樹、遍歷二叉樹(深度、廣度)、求二叉樹的深度(高度)、計算二叉樹的元素個數、計算二叉樹的葉子數、二叉樹的格式輸出等。

根據輸入的符號,執行相應的操作。如下:

C:創建二叉樹,創建成功輸出 “Created success!”。要求實現兩種創建算法。輸入數字“1" ,是根據完全前序序列創建二叉樹,#表示空結點(空子樹);下一行輸入二叉樹的完全前序序列。 輸入數字“2”,是根據二叉樹的前序和中序序列創建二叉樹,後面有三行,分別輸入元素個數、前序序列和中序序列。

H:求二叉樹的高度; 輸出: Height=高度
L:計算二叉樹的葉子數;輸出:Leaves=葉子個數

N:計算二叉樹中元素總個數;輸出:Nodes=結點個數

1:先序遍歷二叉樹;輸出:Preorder is:序列 .

2:中序遍歷二叉樹;輸出:Inorder is:序列 .

3:後序遍歷二叉樹;輸出:Postorder is:序列 .

4:廣度遍歷二叉樹;輸出:BFSorder is:序列 .

F:查找值爲x的結點個數;輸出:The count of x is 個數 .

P:以目錄縮格文本形式輸出所有節點。輸出:The tree is:(換行,下面各行是輸出的二叉樹)

X:退出

測試用例:
輸入:
test1:

C
1
ABC##DE#G##F###
H
L
N
1
2
3
4
F
A
P
X

result1:

Created success!
Height=5
Leaves=3
Nodes=7
Preorder is:A B C D E G F .
Inorder is:C B E G D F A .
Postorder is:C G E F D B A .
BFSorder is:A B C D E F G .
The count of A is 1
The tree is:
A
  B
    C
    D
      E
        G
      F

test2:

C
1
+-*1##2##-3##4##/+5##6##*7##8##
H
L
N
1
2
3
4
F
+
P
X

result2:

Created success!
Height=4
Leaves=8
Nodes=15
Preorder is:+ - * 1 2 - 3 4 / + 5 6 * 7 8 .
Inorder is:1 * 2 - 3 - 4 + 5 + 6 / 7 * 8 .
Postorder is:1 2 * 3 4 - - 5 6 + 7 8 * / + .
BFSorder is:+ - / * - + * 1 2 3 4 5 6 7 8 .
The count of + is 2
The tree is:
+
  -
    *
      1
      2
    -
      3
      4
  /
    +
      5
      6
    *
      7
      8

test3:

C
2
6
abdcef
dbaecf
H
L
N
1
2
3
4
F
+
P
X

result3:

Created success!
Height=3
Leaves=3
Nodes=6
Preorder is:a b d c e f .
Inorder is:d b a e c f .
Postorder is:d b e f c a .
BFSorder is:a b c d e f .
The count of + is 0
The tree is:
a
  b
    d
  c
    e
    f

題意
題目中比較難理解的是那個‘P’:“以目錄縮格文本形式輸出所有節點”,觀察樣例我們可以發現:按行輸出的順序來看,其實是按先根序列的順序輸出,然後每個節點前帶上當前節點所在的層數l*2-2的空格

思路
由先序和中序序列建樹可以參考這篇文章
節點數我們可以在建樹時就求出,葉子數和樹高可以使用層序遍歷求出,查找操作也可以通過層序遍歷完成。

#include <iostream>
#include <queue>
#include <cstdio>
using namespace std;

struct node
{
    char x;
    node* lson;
    node* rson;
    int l;
    node(){l=-1;}
};

char pre[1000],in[1000];
int Height=0,Nodes=0,Leaves=0;
void creat(node* &root,int l)///完全先序序列建樹
{
    root=new node;
    char c;cin>>c;
    if(c=='#') root=NULL;
    else
    {
        root->x=c;
        Nodes++;
        Height=max(l,Height);///計算層高
        creat(root->lson,l+1);
        creat(root->rson,l+1);
    }
}

node* recreat(int prel,int prer,int inl, int inr)///先序中序建樹
{
    if(prel>prer) return NULL;
    node *root=new node;
    root->x=pre[prel];
    int k;
    for(k=inl;k<inr;k++)
    {
        if(in[k]==pre[prel])
            break;
    }
    int num=k-inl;
    root->lson=recreat(prel+1,prel+1+num-1,inl,k-1);
    root->rson=recreat(prel+num+1,prer,k+1,inr);
    return root;
}

void order(node* Node,int type)///先中後序遍歷
{
    if(Node==NULL) return;
    if(type==1)cout<<Node->x<<" ";
    order(Node->lson,type);
    if(type==2)cout<<Node->x<<" ";
    order(Node->rson,type);
    if(type==3)cout<<Node->x<<" ";
}

int Findcnt=0;
char sign;
void LayerOrder(node* e,int type)///type=0計算層高和葉子數,type=1層序遍歷輸出,type=2查找sign有幾個
{
    if(type==1) cout<<"BFSorder is:";
    if(e==NULL) return;
    e->l=1;
    queue<node*> q;
    q.push(e);
    while(!q.empty())
    {
        node* temp=q.front();
        if(type==2&&temp->x==sign) Findcnt++;
        q.pop();
        if(type==1)printf("%c ",temp->x);
        if(temp->lson)
        {
            temp->lson->l=temp->l+1;
            if(type==1)Height=max(Height,temp->lson->l);
            q.push(temp->lson);
        }
        if(temp->rson)
        {
            temp->rson->l=temp->l+1;
            if(type==0)Height=max(Height,temp->rson->l);
            q.push(temp->rson);
        }
        if(type==0&&!temp->rson&&!temp->lson)///沒有左右孩子,說明到葉子節點
            Leaves++;
    }
    if(type==1) cout<<".\n";
    return;
}

void Porder(node* Node)///以目錄縮格文本形式輸出所有節點
{
    if(Node==NULL) return;
    for(int i=1;i<=Node->l*2-2;i++) cout<<' ';
    cout<<Node->x<<'\n';
    Porder(Node->lson);
    Porder(Node->rson);
}

int main()
{
    node* root;
    char c;
    for(int i=1;i<=11;i++)
    {
        cin>>c;
        if(c=='C')
        {
            Nodes=Leaves=Height=0;
            int t;cin>>t;
            if(t==1)  creat(root,1);
            if(t==2)
            {
                int n;cin>>n;Nodes=n;
                for(int i=0;i<n;i++) cin>>pre[i];
                for(int i=0;i<n;i++) cin>>in[i];
                root=recreat(0,n-1,0,n-1);///注意區間是(0,n-1),不是(0,n);否則會多0出來
            }
            LayerOrder(root,0);///計算層高和葉子數
            cout<<"Created success!"<<endl;
        }
        if(c=='H') cout<<"Height="<<Height<<endl;
        if(c=='L') cout<<"Leaves="<<Leaves<<endl;
        if(c=='N') cout<<"Nodes="<<Nodes<<endl;
        if(c=='1'||c=='2'||c=='3')
        {
            if(c=='1')cout<<"Preorder is:";
            if(c=='2')cout<<"Inorder is:";
            if(c=='3')cout<<"Postorder is:";
            order(root,c-'0');
            cout<<".\n";
        }
        if(c=='4') LayerOrder(root,1);
        if(c=='F')
        {
            cin>>sign;
            Findcnt=0;
            LayerOrder(root,2);
            cout<<"The count of "<<sign<<" is "<<Findcnt<<endl;
        }
        if(c=='P')
        {
            cout<<"The tree is:"<<endl;
            Porder(root);
        }
        if(c=='X')return 0;
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章