實驗四 二叉樹的操作 (數據結構實驗C++編寫)

1. 實驗目的

(1)掌握二叉樹的二叉鏈表存儲方式及二叉樹的特徵;
(2)驗證二叉樹在二叉鏈表存儲結構下遍歷操作的實現。

2. 實驗內容

(1)採用二叉鏈表結構建立二叉樹;
(2)編程實現二叉樹的先序、中序、後序和層序遍歷;
(3)編程實現非遞歸中序遍歷;
(4)編程實現:求二叉樹的高度和葉子結點個數。

3. 實驗步驟

(1)編寫程序主框架;
(2)編寫創建二叉樹代碼;
(3)編寫實現二叉樹先序遍歷代碼;
(4)編寫實現二叉樹非遞歸中序遍歷代碼;
(5)編寫實現二叉樹後序遍歷代碼;
(6)編寫實現二叉樹層序遍歷代碼;
(7)編寫求二叉樹高度代碼;
(8)編寫求二叉樹葉子結點個數代碼;
(9)編寫代碼實現哈夫曼算法。

4. 實驗代碼

#include <iostream>
using namespace std;
#define MAXSIZE 100

typedef char ElemType;

//二叉樹
typedef struct BiTNode
{
    ElemType data;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
//順序棧
typedef struct
{
    BiTree *base;
    BiTree *top;
    int stacksize;
}SqStack;
//循環隊列
typedef struct
{
    BiTree *base;
    int frontq;
    int rear;
}SqQueue;

void Tips();
//初始化順序棧
void InitStack(SqStack &S);
//入棧
void Push(SqStack &S,BiTree e);
//出棧
void Pop(SqStack &S,BiTree &e);

//初始化順序隊列
void InitQueue(SqQueue &Q);
//入隊
void enQueue(SqQueue &Q,BiTree e);
//出隊
void deQueue(SqQueue &Q,BiTree &e);
//銷燬隊列
void DestroyQueue(SqQueue &Q);

//建立二叉樹
void CreateBiTree(BiTree &T);
//先序遍歷
void PreOrderTraverse(BiTree &T);
//後序遍歷
void ProOrderTraverse(BiTree &T);
//中序遍歷
void InOrderTraverse(BiTree &T);
//層序遍歷
void SeOrderTraverse(BiTree &T);
//求二叉樹深度
int Depth(BiTree T);
//求葉子結點個數
int NodeCount(BiTree T);


int main()
{
    BiTree T;
    int index;
    Tips();
    do
    {
        cout << "請輸入操作代碼:";
        cin >> index;
        switch(index)
        {
            case 1:
                cout << "輸入:";
                CreateBiTree(T);               //創建二叉樹
                break;
            case 2:
                PreOrderTraverse(T);           //先序遍歷
                cout << endl;
                break;
            case 3:
                ProOrderTraverse(T);           //後序遍歷
                cout << endl;  
                break;
            case 4:
                InOrderTraverse(T);            //非遞歸中序遍歷
                cout << endl;
                break;
            case 5:
                SeOrderTraverse(T);            //層序遍歷
                cout << endl;
                break;
            case 6:
                cout << Depth(T) << endl;      //求二叉樹深度
                break;
            case 7: 
                cout << NodeCount(T) << endl;  //求葉子結點個數
                break;
            default:
                cout << "輸入不合法!" << endl;
                break;
        }

    }while(index>0);


    return 0;
}
void Tips()
{
        cout << "###### 1812050030-戴琦 ######" << endl;
        cout << "1 ---------------- 創建二叉樹" << endl;
        cout << "2 ---------------- 先序遍歷" << endl;
        cout << "3 ---------------- 後序遍歷" << endl;
        cout << "4 ---------------- 非遞歸中序遍歷" << endl;
        cout << "5 ---------------- 層序遍歷" << endl;
        cout << "6 ---------------- 求二叉樹深度" << endl;
        cout << "7 ---------------- 求葉子結點個數" << endl;
        cout << "輸入0或負數退出程序!" << endl;
}
void InitStack(SqStack &S)
{
    S.base = new BiTree[MAXSIZE];
    if(S.base)
    {
        S.top = S.base;
        S.stacksize = MAXSIZE;
    }

}
void Push(SqStack &S,BiTree e)
{
    if(S.top - S.base == MAXSIZE)
        cout << "棧已滿!" << endl;
    else
        *S.top++ = e;
}
void Pop(SqStack &S,BiTree &e)
{
    if(S.base == S.top)
        cout << "棧爲空!" << endl;
    else
        e = *--S.top;
}

void InitQueue(SqQueue &Q)
{
    Q.base = new BiTree[MAXSIZE];
    if(Q.base)
    {
        Q.frontq = Q.rear = 0;
    }

}
void enQueue(SqQueue &Q,BiTree e)
{
    if(Q.frontq == (Q.rear+1)%MAXSIZE)
        cout << "隊列已滿!" << endl;
    else
    {
        Q.base[Q.rear] = e;
        Q.rear = (Q.rear+1) % MAXSIZE;
    }

}
void deQueue(SqQueue &Q,BiTree &e)
{
    if(Q.frontq == Q.rear)
        cout << "隊列爲空!" << endl;
    else
    {
        e = Q.base[Q.frontq];
        Q.frontq = (Q.frontq+1)%MAXSIZE;
    }

}
void DestroyQueue(SqQueue &Q)
{
    if(Q.base)
    {
        Q.frontq = Q.rear;
        delete(Q.base);
    }
}
void CreateBiTree(BiTree &T)
{
    ElemType ch;
    cin >> ch;
    if(ch == '#')
        T = NULL;
    else
    {
        T = new BiTNode;
        T->data = ch;
        CreateBiTree(T->lchild);
        CreateBiTree(T->rchild);
    }
}

void PreOrderTraverse(BiTree &T)
{
   if(T)
   {
       cout << T->data << " ";
       PreOrderTraverse(T->lchild);
       PreOrderTraverse(T->rchild);
   }
}

void ProOrderTraverse(BiTree &T)
{
    if(T)
    {
        ProOrderTraverse(T->lchild);
        ProOrderTraverse(T->rchild);
        cout << T->data << " ";
    }
}

void InOrderTraverse(BiTree &T)
{
    SqStack S;
    InitStack(S);
    BiTree p = T;
    BiTree q = new BiTNode;
    while(p || S.base != S.top)
    {
        if(p)
        {
            Push(S,p);
            p = p->lchild;
        }
        else
        {
            Pop(S,q);
            cout << q->data << " ";
            p = q->rchild;
        }
    }
}
void SeOrderTraverse(BiTree &T)
{
    SqQueue SQ;
    InitQueue(SQ);
    BiTree p = T;
    if(T)
    {
        enQueue(SQ,p);
        while(SQ.frontq != SQ.rear)
        {
            deQueue(SQ,p);
            cout << p->data << " ";
            if(p->lchild)
                enQueue(SQ,p->lchild);
            if(p->rchild)
                enQueue(SQ,p->rchild);
        }
    }
    DestroyQueue(SQ);
}
int Depth(BiTree T)
{
    int m,n;
    if(T == NULL)
        return 0;
    else
    {
        n = Depth(T->lchild);
        m = Depth(T->rchild);
        if(n>m)
            return n+1;
        else
            return m+1;
    }
}
int NodeCount(BiTree T)
{
    if(T == NULL)
        return 0;
    if(!T->lchild && !T->rchild)
        return 1;
    else
        return NodeCount(T->lchild)+NodeCount(T->rchild);
}

5. 實驗總結

(1)二叉樹的遍歷算法是其它運算的基礎,通過遍歷得到二叉樹中結點訪問的線性序列,實現了非線性結構的線性化。
(2)非遞歸中序遍歷二叉樹利用的是棧的後進先出原理;
(3)層序遍歷二叉樹利用的是隊列的先進先出原理。

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