二叉树:建立存储结构(前序输入次序)

二叉树:建立存储结构(前序输入次序)

作者: 冯向阳时间限制: 1S章节: DS:树

截止日期: 2022-06-30 23:55:00

问题描述 :

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

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

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

 

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

要求设计一个递归算法,将二叉树转化为二叉链表的存储形式。

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

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

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

参考函数代码:

//建立二叉树的存储结构 (外壳) 

template<class ElemType>

void CreateTree(BinaryTree<ElemType> &T, ElemType &str, ElemType &empty){

    ElemType tmp;

    vector<ElemType> t;

    

    stringstream input_T(str);

    while(input_T >> tmp){

         t.push_back(tmp);

    }

    BinaryTreeNode<ElemType> *root;

    int num = 0;

    root = T.CreateBinaryTree(t, empty, num);

    T.SetRoot(root);    

}

//建立二叉树的存储结构 (递归部分,成员函数)

template<class ElemType>

BinaryTreeNode<ElemType>* BinaryTree<ElemType>::CreateBinaryTree(vector<ElemType> &x, ElemType &empty, int &n){

        ElemType ch = x[n];

        n++;

        if (ch == empty)

        {

            return NULL;

        }

        else

        {   

            BinaryTreeNode<ElemType> *Node = new BinaryTreeNode<ElemType>;

            Node->data = ch;

            Node->LChild = CreateBinaryTree(x, empty, n);

            Node->RChild = CreateBinaryTree(x, empty, n);

            return Node;

        }

}

二叉树ADT原型参考如下:

/* 二叉表的结点定义 */
template<class ElemType>
struct BinaryTreeNode
{
       ElemType data;
       BinaryTreeNode<ElemType> *LChild, *RChild;
       BinaryTreeNode() : LChild(NULL), RChild(NULL){} //构造函数1,用于构造根结点
       BinaryTreeNode(const ElemType &item, BinaryTreeNode<ElemType> *Lptr = NULL, BinaryTreeNode<ElemType> *Rptr = NULL) //构造函数2,用于构造其他结点  
       //函数参数表中的形参允许有默认值,但是带默认值的参数需要放后面
       {
           LChild = Lptr;
           RChild = Rptr;
           data = item;
       }
      
       ElemType getData(){ return data;}  //取得结点中的数据
       void SetLChild( BinaryTreeNode<ElemType> *link ){ LChild = link; }  //修改结点的左孩子域
       void SetRChild( BinaryTreeNode<ElemType> *link ){ RChild = link; }  //修改结点的右孩子域
       void SetData( ElemType value ){ data = value; }   //修改结点的data域            
       BinaryTreeNode<ElemType> * GetLChild() const{ return LChild;} //获取左孩子结点
       BinaryTreeNode<ElemType> * GetRChild() const{ return RChild;} //获取左孩子结点

};

//二叉树 

template<class ElemType>

class BinaryTree{

   private:

      BinaryTreeNode<ElemType> *root;   // 头指针

      void BinaryTreeDestroy_Cursive( BinaryTreeNode<ElemType> *T ); //销毁树(递归准备,private)

            

   public:

      //无参数的构造函数

      BinaryTree():root(NULL){}

      //带参数的构造函数

      BinaryTree(const ElemType &item){root = new BinaryTreeNode<ElemType>(item);}

      //生成树

      void makeBinaryTree( const ElemType &item, BinaryTree &left, BinaryTree &right); 

      //拷贝构造函数

      //LinkQueue(LinkQueueList<ElemType> &Queue);

      //析构函数

      ~BinaryTree(){BinaryTreeDestroy();}

      //重载函数:赋值

      //LinkList<ElemType>& operator=(LinkList<ElemType> &List);

      //销毁树 

      void BinaryTreeDestroy();

      //销毁子树 

      void ChildDestroy(int flag);

      //返回二叉树结点的个数

      int BinaryTreeSize( BinaryTreeNode<ElemType> *T ) const;

      //判断二叉树是否为空

      bool BinaryTreeisEmpty() const{return root == NULL;}

      //获取根结点元素值 

      ElemType GetRootData() const{ return root->data;}

      //bool Location(ElemType &x, BinaryTreeNode<ElemType> * &location);

      //设置根结点 

      void SetRoot(BinaryTreeNode<ElemType> * p){ root = p;}

      //获取根结点 

      BinaryTreeNode<ElemType> * GetRoot() const{ return root;}

      //前序遍历 

      bool PreOrderTraverse( BinaryTreeNode<ElemType> *T, bool (*visit)(BinaryTreeNode<ElemType> *T, int &num), int &num ) const;  //前序遍历(递归)//num的初始值为0,作用为控制输出格式(最后1个结点后不加“,”)

      //中序遍历 

      bool InOrderTraverse( BinaryTreeNode<ElemType> *T, bool (*visit)(BinaryTreeNode<ElemType> *T, int &num), int &num ) const;  //中序遍历(递归)

      //后序遍历 

      bool PostOrderTraverse( BinaryTreeNode<ElemType> *T, bool (*visit)(BinaryTreeNode<ElemType> *T, int &num), int &num ) const;  //后序遍历(递归)

      //建立二叉树的存储结构

      BinaryTreeNode<ElemType>* CreateBinaryTree(vector<ElemType> &x, ElemType &empty, int &n);

};

输入说明 :

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

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

输出说明 :

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

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

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

输入范例 :

null
A B null C D null null E null null F null G null H null null

输出范例 :

A,B,C,D,E,F,G,H
B,D,C,E,A,F,G,H
D,E,C,B,H,G,F,A


没有用ADT模板~

AC代码:

#include<iostream>
#include<vector>
#include<cstring>
using namespace std;
int m=0,mz=0,mh=0;
typedef struct BinaryTreeNode
{
    string data;
    BinaryTreeNode* LChild,*RChild;
} BinaryTreeNode,*BIT;

void CreateTree(BIT *T,string sym)
{
    string ch;
    cin>>ch;
    if(ch==sym)
    {
        *T=NULL;
    }
    else
    {
        *T=new BinaryTreeNode;
        (*T)->data=ch;
        CreateTree(&(*T)->LChild,sym);
        CreateTree(&(*T)->RChild,sym);
    }
}
void PreOrderTraverse(BIT T)
{
    if(T!=NULL)
    {
        if(m==1)
        {
            cout<<',';
        }
        cout<<T->data;
        m=1;
        PreOrderTraverse(T->LChild);
        PreOrderTraverse(T->RChild);
    }
}
void InOrderTraverse(BIT T)
{
    if(T!=NULL)
    {
        InOrderTraverse(T->LChild);
        if(mz==1)
        {
            cout<<',';
        }
        cout<<T->data;
        mz=1;
        InOrderTraverse(T->RChild);
    }

}
void PostOrderTraverse(BIT T)
{
    if(T!=NULL)
    {
        PostOrderTraverse(T->LChild);
        PostOrderTraverse(T->RChild);
        if(mh==1)
        {
            cout<<',';
        }
        cout<<T->data;
        mh=1;
    }
}
int main()
{
    string sym;
    cin>>sym;
    BIT BT;
    CreateTree(&BT,sym);
    PreOrderTraverse(BT);
    cout<<endl;
    InOrderTraverse(BT);
    cout<<endl;
    PostOrderTraverse(BT);
    cout<<endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值