实验四 二叉树的操作 (数据结构实验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)层序遍历二叉树利用的是队列的先进先出原理。

猜你喜欢

转载自blog.csdn.net/weixin_43790779/article/details/106265471