C++实现一颗完整的二叉树——纯代码


#ifndef CLEARN_BTREE_H
#define CLEARN_BTREE_H
#include<iostream>
#include<vector>
#include<string>
#include<list>
using namespace std;
//定义树的类型,采用二叉链式存储结构
typedef struct node{
    char val;
    node *left;
    node *right;
} BTNode;

class BTree{
public:
    //无参构造器
    BTree(){
        roots = nullptr;
        size = 0;
    }
    //有参构造器
    BTree (const string &data){
        roots = nullptr;
        size = 0;
        roots = createBtree(data);
    }
    //拷贝构造函数
    BTree(BTree &data){
        this->roots = data.roots;
        this->size = data.size;
    }
    //析构函数
    ~BTree(){
        destoryTree(roots);
    }
    //采用前序遍历的方法来输出二叉树,采用递归的方法来输出二叉树
    void midOdrder() {
        midOrder(roots);
        cout << endl;
    }
    void inOrder(){
        inOrder(roots);
        cout<<endl;
    }
    void lastOrder(){
        lastOrder(roots);
        cout<<endl;
    }
    //采用非递归的方式输出二叉树
    //非递归的先序遍历
    void midOrder_by_none_recursion(){
        //采用栈
        vector<BTNode*> stack;
        BTNode *p = roots;
        stack.push_back(p);
        while(!stack.empty()){
            p = stack.back();
            stack.pop_back();
            cout<<p->val<<"  ";
            if(p->right!= nullptr){
                stack.push_back(p->right);
            }
            if(p->left!= nullptr){
                stack.push_back(p->left);
            }
        }
        cout<<endl;
    }
    //非递归的中序遍历
    void inOrder_by_none_recursion(){
        vector<BTNode*> stack;
        BTNode *p = roots;
        while(p!= nullptr||!stack.empty()){
            while(p!= nullptr){
                stack.push_back(p);
                p = p->left;
            }
            if(!stack.empty()){
                p = stack.back();
                stack.pop_back();
                cout<<p->val<<"  ";
                p = p->right;
            }
        }
        cout<<endl;
    }
    //非递归的后序遍历
    void lastOrder_by_none_recursion(){
        BTNode *p,*r;
        bool flag;
        vector<BTNode*> stack;
        p = roots;
        do{
            while (p!= nullptr){
                stack.push_back(p);
                p = p->left;
            }
            r = nullptr;
            flag = true;
            while(!stack.empty()&&flag){
                p = stack.back();
                if(p->right==r){
                    cout<<p->val<<"  ";
                    stack.pop_back();
                    r = p;
                }
                else{
                    p = p->right;
                    flag = false;
                }
            }
        }while(!stack.empty());
        cout<<endl;
    }
    //单层的层次遍历
    void levelOrder(){
        list<BTNode*> queue;
        BTNode *p = roots;
        queue.push_back(p);
        while(!queue.empty()){
            p = queue.front();
            queue.pop_front();
            cout<<p->val<<"  ";
            if(p->left!= nullptr){
                queue.push_back(p->left);
            }
            if(p->right!= nullptr){
                queue.push_back(p->right);
            }
        }
        cout<<endl;
    }
    //一层一层打印二叉树
    void levelOrder_onebyone_layor(){
        list<BTNode*> queue;
        BTNode *p = roots;
        queue.push_back(roots);
        int len,i;
        while(!queue.empty()){
            len = queue.size();
            i = 0;
            while(i<len){
                p = queue.front();
                queue.pop_front();
                cout<<p->val<<"  ";
                if(p->left!= nullptr)
                    queue.push_back(p->left);
                if(p->right!= nullptr)
                    queue.push_back(p->right);
                i++;
            }
            cout<<endl;
        }
    }

    //根据二叉树的先序遍历和中序遍历重建二叉树
    BTree(string midOrder,string inOrder,bool style = false){
        int size = 0;
        if(!style)
            roots = createBtree_by_midOrder_and_inOrder(midOrder,inOrder,0,midOrder.size()-1,0,inOrder.size()-1,size);
        else{
            roots = createBtree_by_lastOrder_and_inOrder(midOrder,inOrder,0,midOrder.size()-1,0,inOrder.size()-1,size);
        }
        this->size = size;
    }
    
    //二叉树的基本运算,输出某个结点的左右孩子
    void getChild(char data){
        getChild(roots,data);
    }
    //输出二叉树的高度
    int treeHeight(){
        return treeHeight(roots);
    }
    //非递归的方式遍历二叉树
private:
    BTNode *roots;
    int size;
    /**
     *   - 如果ch为'('说明其前一个字符是有孩子结点的,那么将此符号入栈,并且先从左节点开始添加,此时k=1
     *   - 当遇到')'说明结点添加结束,将栈顶元素出栈
     *   - 当遇到','将k置为2,说明是右节点的添加
     *   - 其他情况根据k的值添加元素
     * @param data
     * @return
     */
    BTNode* createBtree(string data){
        BTNode *roots = nullptr;
        int k = 1,i=0;
        BTNode *p;
        vector<BTNode*> stack;
        while(i<data.size()){
            switch (data[i]) {
                case'(': stack.push_back(p);k=1;break;
                case ')': stack.pop_back();break;
                case ',': k=2;break;
                default:{
                    p = (BTNode*)malloc(sizeof(BTNode));
                    p->left = p->right = nullptr;
                    p->val = data[i];
                    if(roots == nullptr)
                        roots = p;
                    else{
                        if(k==1){
                            stack.back()->left = p;
                        }else if(k==2){
                            stack.back()->right = p;
                        }
                    }
                    size++;
                }
            }
            i++;
        }
        return roots;
    }

private:
    //销毁一颗二叉树
    void destoryTree(BTNode *&p){
        if(p== nullptr)
            return;
        destoryTree(p->left);
        destoryTree(p->right);
        delete p; //释放指针指向的空间
        p = nullptr; //防止出现空悬指针
    }

private:
    //递归的方法遍历二叉树,从上到下分别为先序遍历、中序遍历、后序遍历
    void midOrder(BTNode *roots){
        if(roots== nullptr)
            return;
        cout<<roots->val<<"  ";
        midOrder(roots->left);
        midOrder(roots->right);
    }
    void inOrder(BTNode *roots){
        if(roots== nullptr)
            return;
        inOrder(roots->left);
        cout<<roots->val<<"  ";
        inOrder(roots->right);
    }
    void lastOrder(BTNode *roots){
        if(roots==nullptr)
            return;
        lastOrder(roots->left);
        lastOrder(roots->right);
        cout<<roots->val<<"  ";
    }
    //输出二叉树中结点的孩子结点
    void getChild(BTNode* roots,char data){
        if(roots== nullptr)
            return;
        if(roots->val == data){
            if(roots->left!= nullptr){
                cout<<roots->left->val<<"  ";
            }
            if(roots->right!=nullptr){
                cout<<roots->right->val<<"  ";
            }
            cout<<endl;
            return;
        }
        getChild(roots->left,data);
        getChild(roots->right,data);
    }
    //输出二叉树中某个结点的双亲结点

private:
    //求树的高度
    int treeHeight(BTNode *roots){
        if(roots== nullptr)
            return 0;
        return 1+ max(treeHeight(roots->left), treeHeight(roots->right));
    }
private:
    //根据中序遍历和先序遍历恢复一颗二叉树
    BTNode* createBtree_by_midOrder_and_inOrder( string &preOrder,string &inOrder
            ,int pre_start,int pre_end,int in_start,int in_end,int &size){
        BTNode *p = (BTNode*) malloc(sizeof(BTNode));
        size++;
        p->val = preOrder[pre_start];
        p->left = nullptr;
        p->right = nullptr;
        int k = in_start;
        for(;k<in_end;k++){
            if(preOrder[pre_start]==inOrder[k])
                break;
        }
        if(pre_start==pre_end)
            return p;
        else{
            if(k==in_start){
                p->right = createBtree_by_midOrder_and_inOrder(preOrder,inOrder,pre_start+1,pre_end,k+1,in_end,size);
            }
            else if(k==in_end){
                p->left = createBtree_by_midOrder_and_inOrder(preOrder,inOrder,pre_start+1,pre_end,in_start,k-1,size);
            }
            else{
                p->left = createBtree_by_midOrder_and_inOrder(preOrder,inOrder,pre_start+1,pre_start+k-in_start,in_start,k-1,size);
                p->right = createBtree_by_midOrder_and_inOrder(preOrder,inOrder,pre_start+k-in_start+1,pre_end,k+1,in_end,size);
            }
        }
        return p;
    }
    //根据中序遍历和后序遍历恢复一颗二叉树
    BTNode* createBtree_by_lastOrder_and_inOrder(string &lastOrder,string &inOrder,int last_start,int last_end,int in_start,int in_end,int &size){
        BTNode *p = (BTNode*)malloc(sizeof(BTNode));
        p->val = lastOrder[last_end];
        p->left = nullptr;
        p->right = nullptr;
        size++;
        int k = in_start;
        for(;k<in_end;k++){
            if(inOrder[k]==lastOrder[last_end])
                break;
        }
        if(last_end==last_start)
            return p;
        if(k==in_start){
            p->right = createBtree_by_lastOrder_and_inOrder(lastOrder,inOrder,last_start,last_end-1,k+1,in_end,size);
        }else if(k==in_end){
            p->left = createBtree_by_lastOrder_and_inOrder(lastOrder,inOrder,last_start,last_end-1,in_start,k-1,size);
        }else{
            p->left = createBtree_by_lastOrder_and_inOrder(lastOrder,inOrder,last_start,last_start+k-in_start-1,in_start,k-1,size);
            p->right = createBtree_by_lastOrder_and_inOrder(lastOrder,inOrder,last_start+k-in_start,last_end-1,k+1,in_end,size);
        }
        return p;
    }
};

#endif //CLEARN_BTREE_H

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值