二叉树:前序、中序、后序遍历

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

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

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

(2)基本操作:在二叉树的二叉链表存储形式建立的基础上,设计二叉树的三种遍历算法:前序、中序和后序。完成后将它们加入到二叉树的ADT基本操作集中。

要求使用递归的程序设计方法,设计并完成二叉树的三种遍历算法。

初始条件:二叉树T存在,visit是对结点操作的应用函数。

操作结果:先序(中序、后序)遍历T,对每个结点调用函数visit一次且仅一次。一旦visit()失败,则操作失败。

参考函数原型:

(1)visit函数(具体功能根据实际需要,样例仅仅输出data域的信息)

template<class ElemType>

bool visit(BinaryTreeNode<ElemType> * root, int &num){    

    if(!root) return false; 

    else{

        if(num==0){//控制输出格式

              cout<<root->data;

              num++;

        }

        else cout<<","<<root->data;     

        return true;

    }    

}     

     

(2)基本操作2:前序遍历

//前序遍历(外壳部分,用户函数) 

template<class ElemType>

bool PreOrderTraverse(BinaryTree<ElemType> &T);

//前序遍历(递归部分,成员函数) 

template<class ElemType>

bool BinaryTree<ElemType>::PreOrderTraverse( BinaryTreeNode<ElemType> *T, bool (*visit)(BinaryTreeNode<ElemType> *T, int &num), int &num ) const;

(3)基本操作3:中序遍历

//中序遍历(外壳部分,用户函数) 

template<class ElemType>

bool InOrderTraverse(BinaryTree<ElemType> &T);

//中序遍历(递归部分,成员函数) 

template<class ElemType>

bool BinaryTree<ElemType>::InOrderTraverse( BinaryTreeNode<ElemType> *T, bool (*visit)(BinaryTreeNode<ElemType> *T, int &num), int &num ) const;

(4)基本操作4:后序遍历

//后序遍历(外壳部分,用户函数) 

template<class ElemType>

bool PostOrderTraverse(BinaryTree<ElemType> &T);

//后序遍历(递归部分,成员函数) 

template<class ElemType>

bool BinaryTree<ElemType>::PostOrderTraverse( BinaryTreeNode<ElemType> *T, bool (*visit)(BinaryTreeNode<ElemType> *T, int &num), int &num ) const;

感觉这种用抽象数据类型的比直接用函数麻烦好多,不过题目要求用ADT的话就慢慢写啦~

话不多说,上代码


#include<iostream>
#include<cstring>
#include<vector>
#include<sstream>
using namespace std;
/* 二叉表的结点定义 */
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>
bool visit(BinaryTreeNode<ElemType> *root,int &num)
{
    if(!root)
        return false;
    else
    {
        if(num==0)
        {
            cout<<root->data;
            num++;
        }
        else
            cout<<","<<root->data;
        return true;
    }
}
//二叉树
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 Pre(BinaryTreeNode<ElemType> *T,bool(*visit)(BinaryTreeNode<ElemType> *T,int &num),int &num) const; //前序遍历(递归)//num的初始值为0,作用为控制输出格式(最后1个结点后不加“,”)
//中序遍历
    bool In(BinaryTreeNode<ElemType> *T,bool(*visit)(BinaryTreeNode<ElemType> *T,int &num),int &num) const; //中序遍历(递归)
//后序遍历
    bool Post(BinaryTreeNode<ElemType> *T,bool(*visit)(BinaryTreeNode<ElemType> *T,int &num),int &num) const; //后序遍历(递归)
//建立二叉树的存储结构
    BinaryTreeNode<ElemType>* CreateBinaryTree(vector<ElemType> &x, ElemType &sym, int &n);
};
//建立二叉树的存储结构 (递归部分,成员函数)
template<class ElemType>
BinaryTreeNode<ElemType>* BinaryTree<ElemType>::CreateBinaryTree(vector<ElemType> &x, ElemType &sym, int &n)
{
    ElemType ch = x[n];
    n++;
    if (ch == sym)
    {
        return NULL;
    }
    else
    {
        BinaryTreeNode<ElemType> *Node = new BinaryTreeNode<ElemType>;
        Node->data = ch;
        Node->LChild = CreateBinaryTree(x, sym, n);
        Node->RChild = CreateBinaryTree(x, sym, n);
        return Node;
    }
}
//建立二叉树的存储结构 (外壳)
template<class ElemType>
void CreateTree(BinaryTree<ElemType> &T, ElemType &str, ElemType &sym)
{
    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,sym,num);
    T.SetRoot(root);
}
template<class ElemType>
void BinaryTree<ElemType>::makeBinaryTree(const ElemType &item, BinaryTree &left, BinaryTree &right)
{
    root=new BinaryTreeNode<ElemType>(item,left.root,right.root);
    left.root=NULL;
    right.root=NULL;
}
//前序遍历
template<class ElemType>
bool BinaryTree<ElemType>::Pre(BinaryTreeNode<ElemType> *T,bool(*visit)(BinaryTreeNode<ElemType> *T,int &num),int &num) const
{
//成员函数,递归
    if(T==NULL)
        return false;
    visit(T,num);
    Pre(T->LChild,visit,num);
    Pre(T->RChild,visit,num);
}
template<class ElemType>
bool Pre(BinaryTree<ElemType> &T)
{
//用户函数
    BinaryTreeNode<ElemType> *p=T.GetRoot();
    int num=0;
    T.Pre(p,visit,num);
}
//中序遍历
template<class ElemType>
bool BinaryTree<ElemType>::In(BinaryTreeNode<ElemType> *T,bool(*visit)(BinaryTreeNode<ElemType> *T,int &num),int &num) const
{
//成员函数,递归
    if(T==NULL)
        return false;
    In(T->LChild,visit,num);
    visit(T,num);
    In(T->RChild,visit,num);
}

template<class ElemType>
bool In(BinaryTree<ElemType> &T)
{
//用户函数
    BinaryTreeNode<ElemType> *p=T.GetRoot();
    int num=0;
    T.In(p,visit,num);
}
//后序遍历
template<class ElemType>
bool BinaryTree<ElemType>::Post(BinaryTreeNode<ElemType> *T,bool(*visit)(BinaryTreeNode<ElemType> *T,int &num),int &num) const
{
//成员函数,递归
    if(T==NULL)
        return false;
    Post(T->LChild,visit,num);
    Post(T->RChild,visit,num);
    visit(T,num);
}
template<class ElemType>
bool Post(BinaryTree<ElemType> &T)
{
//用户函数
    BinaryTreeNode<ElemType> *p=T.GetRoot();
    int num=0;
    T.Post(p,visit,num);
}
int main()
{
    BinaryTree<string>BT;
    string mytree;
    string sym;
    getline(cin,sym);
    getline(cin,mytree);
    CreateTree(BT,mytree,sym);
    Pre(BT);
    cout<<endl;
    In(BT);
    cout<<endl;
    Post(BT);
    return 0;
}


这样用这个模板,然后后面二叉树抽象数据类型的挺多题目应该可以套用,所以应该是挺有用滴。

嘿嘿,int main 里的前面几句话最好记住哦。我的第一篇博客,谢谢支持!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值