dhu 5.2 二叉树:建立存储结构(层次次序)

28 篇文章 5 订阅

二叉树:建立存储结构(层次次序)
时间限制: 1S类别: DS:树->中等

晚于: 2022-05-22 23:55:00后提交分数乘系数50%

截止日期: 2022-05-29 23:55:00

问题描述 :

目的:使用C++模板设计并逐步完善二叉树的抽象数据类型(ADT)。

内容:(1)请参照链表的ADT模板,设计二叉树并逐步完善的抽象数据类型。(由于该环境目前仅支持单文件的编译,故将所有内容都集中在一个源文件内。在实际的设计中,推荐将抽象类及对应的派生类分别放在单独的头文件中。参考教材、课件,以及网盘中的链表ADT原型文件,自行设计二叉树的ADT。)

注意:二叉树ADT的基本操作的算法设计很多要用到递归的程序设计方法。

(2)基本操作:二叉树的二叉链表存储形式的建立,完成后将其加入到二叉树的ADT基本操作集中。

输入数据为层次次序,要求设计一个算法,将二叉树转化为二叉链表的存储形式。

初始条件:definition给出二叉树T的定义(自然输入顺序序列。无孩子或指针为空的情形,算法通过特殊分隔符识别(输入)),至少有1个根结点。

输出:按definition构造二叉树的二叉链表。

注意:由于测试数据的显示需建立在二叉树的遍历基础上。因此,请在设计好二叉树的三种遍历算法之后(基本操作2),再进行测试。

参考函数原型:

//建立二叉树的存储结构 (用户函数)

template

void CreateTree_Layer(BinaryTree &T, ElemType &str, ElemType &empty);

输入说明 :

第一行:表示无孩子或指针为空的特殊分隔符

第二行:二叉树的层次次序序列(结点元素之间以空格分隔)

输出说明 :

第一行:二叉树先序遍历结果

第二行:二叉树中序遍历结果

第三行:二叉树后序遍历结果

输入范例 :

    • 62 * / # # + 3 400 + 12 14 # # # # 30 * # # # # # # 10 5
      输出范例 :

+,-,,+,12,14,3,/,400,+,30,,10,5,62
12,+,14,,3,-,400,/,30,+,10,,5,+,62
12,14,+,3,,400,30,10,5,,+,/,-,62,+

#include <iostream>
#include <cstring>
#include <string>
using namespace std;
#define Status int
#define MAXSIZE 100
//二叉树的链表存储形式
typedef string TElemType;
typedef string SElemType;
//链栈结点定义
typedef struct StackNode
{
    SElemType data;
    struct StackNode* next;
}StackNode, * LinkStack;
//链栈的初始化
Status InitStack(LinkStack& S)
{//构造一个空栈S
    S = NULL;        //栈顶指针即S
    return 1;
}
//链栈的出栈
Status Pop(LinkStack& S, SElemType& e)
{//删除S的栈顶元素,用e返回
    if (S == NULL) return 0;       //判断空栈
    StackNode* p = S;              //将栈顶临时赋给p
    S = S->next;                   //删除
    delete p;                      //释放空间
    return 1;
}
SElemType GetTop(LinkStack& S)
{
    if (S == NULL) return 0;       //判断空栈
    return S->data;                //返回栈顶元素值
}
Status Push(LinkStack& S, SElemType e)
{
    StackNode* p = new StackNode;              //生成新结点
    p->data = e;                               //将新结点数据域置为e
    p->next = S;                               //将新结点插入栈顶
    S = p;                                     //修改栈顶指针为p
    return 1;
}
//顺序栈的存储结构
typedef struct
{
    SElemType* base;
    SElemType* top;
    int stacksize;			//可用最大容量
}SqStack;
//遍历输出栈
void printStack(LinkStack S)
{
    StackNode* p = S;
    while (p != NULL)
    {
        cout << p->data;
        if (p->next != NULL)
            cout << ",";
        p = p->next;
    }
}
void change(LinkStack &S1, LinkStack &S2)
{
    StackNode* p = S1;
    SElemType e = " ";
    while (p != NULL)
    {
        Push(S2, p->data);
        p = p->next;
        Pop(S1, e);
    }
}
typedef struct BiNode
{
    TElemType data;                      //结点数据域
    struct BiNode* lchild, * rchild; //左右孩子指针
} BiTNode, * BiTree;
Status InitBiTree(BiTree& T,string str)//构造空二叉树T( 先序序列)
{
    //按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
    string ch;
    cin >> ch;
    if (ch == str)
        T = NULL; //递归结束,建空树
    else
    {
        T = new BiTNode;
        T->data = ch;            //生成根结点
        InitBiTree(T->lchild,str); //递归创建左子树
        InitBiTree(T->rchild,str); //递归创建右子树
    }
    return 1;
}
Status InitBiTree1(BiTree& T, string str)//构造空二叉树T( 层次序列)
{
    string ch;
    getline(cin, ch);
    char s[1000] = { 0 };
    strcpy(s,ch.c_str());
    BiTNode* m[1000]={0};
    int n = 0;
    int i = 0, k = 0;
    for (i = 0; s[i] != 0&&s[i]!=-2; i++)
    {
        string ch2="";
        for (k = i; s[k] != ' '&&s[k]!=0; k++)
        { 
            ch2 += s[k];
        }
        BiTree T = new BiTNode;
        if (ch2 == str)
            T = NULL;
        else
        {
            T->data = ch2;            //生成根结点
            T->lchild = NULL;
            T->rchild = NULL;
        }
        m[n] = T;
        n++;
        i = k;
    }
    int num = n;
    n = 1, i = 0;
    BiTNode* father = m[i];
    BiTNode* child = m[n];
    while (n != num)
    {
        if (n % 2 != 0)
            father->lchild = child;
        else
        {
            father->rchild = child;
            if (num != n + 1)
            {
                i++;
                while (m[i] == NULL)
                    i++;
            }
        }
        n++;
        father = m[i]; child = m[n];
    }
    T = m[0]; 
    return 1;
}
Status ClearNode(BiTNode *T)//清除叶子
{
    delete T;
    return 1;
}
Status ClearBiTree(BiTree &T)//将二叉树清为空树(差根结点
{
    if (T->lchild != NULL&& T->rchild != NULL)
    {
        if (T->lchild != NULL)
            ClearBiTree(T->lchild);
        if (T->rchild != NULL)
            ClearBiTree(T->rchild);
    }
    else
        ClearNode(T);
    return 1;
}
Status DestroyBiTree(BiTree &T)//销毁二叉树(需上面那个递归函数
{
    ClearBiTree(T);
    ClearNode(T);
    T = NULL;
    return 1;
}
bool BiTreeEmpty(BiTree T)//若T为空二叉树,返回1
{
    if (T!=NULL)
        return 0;
    else
        return 1;
}
int BiTreeDepth(BiTree T)//返回二叉树深度
{
    int m, n;
    if (T == NULL)
        return 0; //如果是空树,深度为0,递归结束
    else
    {
        m = BiTreeDepth(T->lchild); //递归计算左子树的深度记为m
        n = BiTreeDepth(T->rchild); //递归计算右子树的深度记为n
        if (m > n)
            return (m + 1); //二叉树的深度为m 与n的较大者加1
        else
            return (n + 1);
    }
}
BiTNode *ROOT(BiTree& T)//返回根结点
{
    BiTNode *p = T;
    return p;
}
BiTNode *Value(BiTree T, TElemType e)//返回值为e的结点
{
    BiTree Q[MAXSIZE];
    int front = 0, rear = 0;
    BiTree p;
    if (T)
    {
        Q[rear] = T;
        rear++;
        while (front != rear)/*队列不空*/
        {
            p = Q[front];/*出队*/
            front = (front + 1) % MAXSIZE;
            if (p->data == e)/*如果找到*/
                return p;
            if (p->lchild)/*左树入队*/
            {
                Q[rear] = p->lchild;
                rear = (rear + 1) % MAXSIZE;
            }
            if (p->rchild)/*右树入队*/
            {
                Q[rear] = p->rchild;
                rear = (rear + 1) % MAXSIZE;
            }
        }
    }
    return NULL;
}
void Assign(BiTree T, TElemType e, TElemType value)//结点e赋值为value
{
    BiTNode *p= Value(T, e);
    p->data = value;
    return;
}
BiTNode *arent(BiTree T, TElemType e)//返回双亲,否则返回空
{
    BiTNode* p;
    if (T->lchild != NULL)
        if (T->lchild->data == e)
            return T;
    if (T->rchild != NULL)
        if (T->rchild->data == e)
            return T;
    if (T->lchild != NULL)
    {
        p = arent(T->lchild, e);
        if(p!=NULL)
            return arent(T->lchild, e);
    }
    if (T->rchild != NULL)
    {
        p = arent(T->rchild, e);
        if (p!=NULL)
            return arent(T->rchild, e);
    }
    return NULL;
}
BiTNode *LeftChild(BiTree T, TElemType e)//返回左孩子,否则返回空
{
    BiTNode* p = Value(T, e);
    return p->lchild;
}
BiTNode *RightChild(BiTree T, TElemType e)//返回右孩子,否则返回空
{
    BiTNode* p = Value(T, e);
    return p->rchild;
}
void PreOrderTraverse(BiTree T,LinkStack &S)//先序遍历
{
    if (T == NULL) { return; }
    Push(S, T->data);
    PreOrderTraverse(T->lchild,S);
    PreOrderTraverse(T->rchild,S);    
}
void InOrderTraverse(BiTree T, LinkStack& S)//中序遍历
{
    if (T == NULL) { return; }
    InOrderTraverse(T->lchild,S);
    Push(S, T->data);
    InOrderTraverse(T->rchild,S);
}
void PostOrderTraverse(BiTree T, LinkStack& S)//后序遍历
{
    if (T == NULL) {return;}
    PostOrderTraverse(T->lchild,S);
    PostOrderTraverse(T->rchild,S);
    Push(S, T->data);
}
void _BTreeLevelOrder(BiTNode* root, int i,LinkStack &S)
{
    if (root == NULL || i == 0)
    {
        return;
    }
    if (i == 1)
    {
        Push(S,root->data);
        return;
    }
    _BTreeLevelOrder(root->lchild, i - 1,S);
    _BTreeLevelOrder(root->rchild, i - 1,S);
}
void BTreeLevelOrder(BiTNode* root,LinkStack &S)
{
    if (root == NULL)
        return;
    int dep = BiTreeDepth(root); 
    for (int i = 1; i <= dep; i++)
    {
        _BTreeLevelOrder(root, i,S);
    }
}
void clear(LinkStack& S)//清空栈
{
    StackNode* p = S;
    SElemType e=" ";
    while (p != NULL)
    {
        p = p->next;
        Pop(S,e);
    }
}
void change(BiTNode* T)//交换左右结点
{
    BiTNode* p = T->lchild;
    T->lchild = T->rchild;
    T->rchild = p;
    return ;
}
void solution(BiTree T)//后序遍历
{
    if (T == NULL) { return; }
    solution(T->lchild);
    solution(T->rchild);
    change(T);
}
void Preprinttree(BiTree T, LinkStack& S1, LinkStack& S2)//先序输出
{
    PreOrderTraverse(T, S1);
    change(S1, S2);
    printStack(S2);
    clear(S2);
    cout << endl;
}
void Inprinttree(BiTree T, LinkStack& S1, LinkStack& S2)//中序
{
    InOrderTraverse(T, S1);
    change(S1, S2);
    printStack(S2);
    clear(S2);
    cout << endl;
}
void Postprinttree(BiTree T, LinkStack& S1, LinkStack& S2)//后序
{
    PostOrderTraverse(T, S1);
    change(S1, S2);
    printStack(S2);
    clear(S2);
    cout << endl;
}
int main()
{
    string str,ch;
    cin >> str;
    cin.get();
    BiTree T;
    InitBiTree1(T,str);
    LinkStack S1, S2;
    InitStack(S1); InitStack(S2);
    Preprinttree(T,S1,S2);
    Inprinttree(T, S1,S2);
    Postprinttree(T, S1, S2);
    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值