上机作业之树:二叉树遍历算法、由遍历序列构造二叉树算法

题目:
1. 定义二叉树类,封装构造二叉树基本操作,广度优先遍历,深度优先遍历(递归和非递归算法)等。
2. 实现由先序、中序序列构造二叉树的算法。
3. 实现由后序、中序序列构造二叉树的算法。

//
//  main.cpp
//  BinaryTree
//
//  Created by Cyril on 2016/11/8.
//  Copyright © 2016年 Cyril. All rights reserved.
//

#include 
#include 
#include 
using namespace std;
//二叉树结点的定义
template <class T>
class BT;

template <class T>
class BTNode
{
    friend class BT;
private:
    T data;
    BTNode *lChild;
    BTNode *rChild;
public:
    BTNode();
    BTNode(T& d);//给定数据域的值得构造函数
    BTNode(T& d, BTNode *l, BTNode *r);//给定数据域以及左右孩子的构造函数
    BTNode *GetLChild();//返回左孩子结点的指针
    BTNode *GetRChild();//返回右孩子结点的指针
    void SetLChild(BTNode *l);//设置左孩子结点
    void SetRChild(BTNode *r);//设置右孩子结点
    ~BTNode(){}
    T GetValue();//返回该节点数据值
    bool SetValue(T& val);//设置该点数据值
    bool IsLeaf();//判断是否为叶子结点
    void DisplayNode();//输出结点
};
template <class T>
BTNode::BTNode()
{
    lChild=rChild=NULL;
}
template <class T>
BTNode::BTNode(T& d)//给定数据域的值得构造函数
{
    lChild=rChild=NULL;
    data=d;
}
template <class T>
BTNode::BTNode(T& d, BTNode *l, BTNode *r)//给定数据域以及左右孩子的构造函数
{
    lChild=l;
    rChild=r;
    data=d;
}
template <class T>
BTNode* BTNode:: GetLChild()//返回左孩子结点的指针
{
    return lChild;
}
template <class T>
BTNode* BTNode:: GetRChild()//返回右孩子结点的指针
{
    return rChild;
}
template <class T>
void BTNode:: SetLChild(BTNode *l)//设置左孩子结点
{
    lChild=l;
}
template <class T>
void BTNode:: SetRChild(BTNode *r)//设置右孩子结点
{
    rChild=r;
}
template <class T>
T BTNode:: GetValue()//返回该节点数据值
{
    return data;
}
template <class T>
bool BTNode:: SetValue(T& val)//设置该点数据值
{
    this->data=val;
    return true;
}
template <class T>
bool BTNode:: IsLeaf()//判断是否为叶子结点
{
    if(lChild==NULL&&rChild==NULL)
        return true;
    else
        return false;
}
template <class T>
void BTNode:: DisplayNode()//输出结点
{
    cout<<"该结点的数据为: "<//二叉树类的定义
template <class T>
class BT
{
private:
    BTNode *root;//二叉树的根节点
public:
    BT(){root=NULL;}
    ~BT(){}
    void NewTree();//创建新树
    BTNode* SetSubTree();//创建子树并返回子树的根结点地址
    bool IsEmpty();//判断是否为空树
    BTNode* GetRoot();//返回根节点
    bool GetParent(BTNode *cur);//返回当前结点的父节点.(未实现)
    bool GetLSibling(BTNode *cur);//返回当前结点的左兄弟.(未实现)
    bool GetRSibling(BTNode *cur);//返回当前结点的右兄弟.(未实现)

    bool LevelOrder(BTNode *r);//广度优先遍历(非递归)
    bool PreOrder(BTNode *r);//前序遍历(递归)
    bool PreOrderWithoutRecusion(BTNode *r);//前序遍历(非递归)
    bool InOrder(BTNode *r);//中序遍历(递归)
    bool InOrderWithoutRecusion(BTNode *r);//中序遍历(非递归)
    bool PostOrder(BTNode *r);//后序遍历(递归)
    bool PostOrderWithoutRecusion(BTNode *r);//后序遍历(非递归)

    bool DeleteNode(BTNode *r);//删除以r为根结点的子树.(未实现)
    void Display();//输出树
    void RecDisplay(BTNode *t);//用于输出树时的循环迭代

    void PreInCreateTree(string &pre, string &in);//前序中序构造二叉树
    BTNode* PreInCreate(string &pre, string &in);//用于前序、中序构造二叉树
    void PostInCreateTree(string &post, string &in);//后序中序构造二叉树
    BTNode* PostInCreate(string &post, string &in);//用于后序、中序构造二叉树

};
template <class T>
void BT::NewTree()//创建新树
{
    cout<<"请输入根结点的数据:"<template <class T>
BTNode* BT::GetRoot()//返回根节点
{
    return root;
}
template <class T>
BTNode* BT:: SetSubTree()//创建子树并返回子树的根结点地址
{
    T t;
    cin>>t;
    BTNode *p;
    if(t=='#')
        return NULL;//返回空指针
    else
    {
        p=new BTNode;
        p->SetValue(t);
        //cout<<"成功读入"<
        cout<<"请输入左孩子结点的数据:(输入‘#’则表示不存在左孩子结点)"<SetLChild(SetSubTree());
        cout<<"请输入右孩子结点的数据:(输入‘#’则表示不存在左孩子结点)"<SetRChild(SetSubTree());
        return p;
    }
}
template <class T>
bool BT:: IsEmpty()//判断是否为空树
{
    return !root;
}

template <class T>
BTNode* BT:: PreInCreate(string &pre, string &in)//用于前序、中序构造二叉树
{
    if(pre.length()!=in.length())
        return NULL;//长度不一样则返回错
    char ele;//临时存储字符
    BTNode *p;
    ele=pre[0];
    if(!ele)
        return NULL;
    else
    {
        p=new BTNode;
        p->SetValue(ele);
        int index=(int)in.find(ele);
        string PreLeft=pre.substr(1,index);
        string InLeft=in.substr(0,index);
        string PreRight=pre.substr(index+1);
        string InRight=in.substr(index+1);
        p->SetLChild(PreInCreate(PreLeft,InLeft));
        p->SetRChild(PreInCreate(PreRight,InRight));
        return p;
    }
}
template <class T>
void BT:: PreInCreateTree(string &pre, string &in)//前序中序构造二叉树
{
    root=PreInCreate(pre,in);
}
//
template <class T>
BTNode* BT:: PostInCreate(string &post, string &in)//用于后序、中序构造二叉树
{
    if(post.length()!=in.length())
        return NULL;//长度不一样则返回错
    char ele;//临时存储字符
    BTNode *q;
    if(!post[0])
        return NULL;
    else
    {
        ele=post[post.length()-1];
        q=new BTNode;
        q->SetValue(ele);
        int index=(int)in.find(ele);
        string PostLeft=post.substr(0,index);
        string InLeft=in.substr(0,index);
        string PostRight=post.substr(index,in.length()-(index+1));
        string InRight=in.substr(index+1);
        q->SetLChild(PostInCreate(PostLeft,InLeft));
        q->SetRChild(PostInCreate(PostRight,InRight));
        return q;
    }
}
template <class T>
void BT:: PostInCreateTree(string &post, string &in)//后序中序构造二叉树
{
    root=PostInCreate(post,in);
}

template <class T>
bool BT:: LevelOrder(BTNode *r)//广度优先遍历(非递归)
{
    queue*> NodeQueue;
    BTNode *p=root;
    if(p)
        NodeQueue.push(p);
    while (!NodeQueue.empty())
    {
        p=NodeQueue.front();
        //...访问p指针指向的结点
        //样例操作:广度优先输出树
        cout<data<<' ';
        NodeQueue.pop();
        if(p->lChild)
            NodeQueue.push(p->lChild);
        if(p->rChild)
            NodeQueue.push(p->rChild);
    }
    return true;
}
template <class T>
bool BT:: PreOrder(BTNode *r)//前序遍历(递归)
{
    if(r)
    {
        //...访问r指针指向的结点
        //样例操作:深度优先输出树
        cout<data<<' ';
        PreOrder(r->lChild);
        PreOrder(r->rChild);
    }
    return true;
}
template <class T>
bool BT:: InOrder(BTNode *r)//中序遍历(递归)
{
    if(r)
    {
        InOrder(r->lChild);
        //...访问r指针指向的结点
        //样例操作:深度优先输出树
        cout<data<<' ';
        InOrder(r->rChild);
    }
    return true;
}
template <class T>
bool BT:: PostOrder(BTNode *r)//后序遍历(递归)
{
    if(r)
    {
        PostOrder(r->lChild);
        PostOrder(r->rChild);
        //...访问r指针指向的结点
        //样例操作:深度优先输出树
        cout<data<<' ';
    }
    return true;
}
template <class T>
bool BT:: PreOrderWithoutRecusion(BTNode *r)//前序遍历(非递归)
{
    BTNode *p;
    p=r;
    stack*> NodeStack;
    while (!NodeStack.empty()||p)//栈为空或还有结点
    {
        if(p)
        {
            //...访问p指针指向的结点
            //深度优先输出树
            cout<data<<' ';
            if(p->rChild)
            {
                NodeStack.push(p->rChild);
            }
            p=p->lChild;
        }
        else
        {
            p=NodeStack.top();
            NodeStack.pop();
        }
    }
    return true;
}
template <class T>
bool BT:: InOrderWithoutRecusion(BTNode *r)//中序遍历(非递归)
{
    BTNode *p;
    p=r;
    stack*> NodeStack;
    while (!NodeStack.empty()||p)//栈为空或还有结点
    {
        if(p)
        {
            NodeStack.push(p);
            p=p->lChild;
        }
        else
        {
            p=NodeStack.top();
            NodeStack.pop();
            //...访问p指针指向的结点
            //深度优先输出树
            cout<data<<' ';
            p=p->rChild;
        }
    }
    return true;
}
template <class T>
bool BT:: PostOrderWithoutRecusion(BTNode *r)//后序遍历(非递归)
{
    stack*> NodeStack;
    BTNode *pre,*p;
    pre=p=r;
    while(p)
    {
        for(;p->lChild;p=p->lChild)
            NodeStack.push(p);
        while (p&&(!p->rChild||p->rChild==pre))//没有右孩子或者右孩子刚被访问过
        {
            //...访问p指针指向的结点
            //深度优先输出树
            cout<data<<' ';
            if(NodeStack.empty())
                return true;
            pre=p;
            p=NodeStack.top();
            NodeStack.pop();
        }
        NodeStack.push(p);
        p=p->rChild;//转向右孩子
    }
    return true;
}
template <class T>
void BT:: Display()
{
    //cout<<"进行到这里了,且root为"<
    RecDisplay(root);
    cout<template <class T>
void BT:: RecDisplay(BTNode *t)
{
    if(t!=NULL)
    {
        cout<data;
        if(t->lChild||t->rChild)
        {
            cout<<'(';
            RecDisplay(t->lChild);
            cout<<',';
            if(t->rChild)
                RecDisplay(t->rChild);
            else
                cout<<'#';
            cout<<')';
        }
    }
    else
    {
        cout<<'#';
    }
}

int main()
{
    BT<char> Tree;
    Tree.NewTree();
    Tree.Display();
    cout<<"广度优先遍历如下"<cout<"前序遍历如下(递归)"<cout<"前序遍历如下(非递归)"<cout<"中序遍历如下(递归)"<cout<"中序遍历如下(非递归)"<cout<"后序遍历如下(递归)"<cout<"后序遍历如下(非递归)"<cout<cout<<"前序序列为:";
    string a="ABCDEGF";
    cout<cout<<"中序序列为:";
    string b="CBEGDFA";
    cout<cout<<"现在按前序、中序序列构造二叉树如下:"<cout<<"后序序列为:";
    string c="CGEFDBA";
    cout<cout<<"中序序列为:";
    string d="CBEGDFA";
    cout<cout<<"现在按后序、中序序列构造二叉树如下:"<return 0;
}

以下为按要求输入后,所得到的输出情况:

上机作业之树:二叉树遍历算法、由遍历序列构造二叉树算法_第1张图片


本人为在校学生,仅仅为了记录学习历程,算法不当或过于低级请谅解,也欢迎大家指出其中的错误,啦啦啦 >_<

你可能感兴趣的:(数据结构上机代码)