c++二叉树的建立、前序中序后序深搜、宽搜、宽搜带行号

来源:互联网 发布:微信小程序php实例 编辑:程序博客网 时间:2024/04/29 22:46
c++中用模板类建立树的抽象结构要注意c++中的类模板不能实现分离编译,即定义在.h文件,实现在.cpp文件,因此要将定义和实现都写在.h文件中
原因见:http://blog.csdn.net/pongba/article/details/19130


输入的树形为:


输入文件内容为:
A B D G # # H # # E # # C K # # F I # J # # #

输出的结果为:(前序,中序,后序,层序,以及按层号输出)
A B D G H E C K F I J 
G D H B E A K C I J F 
G H D E B K J I F C A 
A B C D E K F G H I J 
B C 
D E K F 
G H I 
J
 
.h文件中代码如下,都是非递归的方式实现宽搜和深搜:
//
// Created by Alina on 16/3/11.
//

#ifndef FORJOB_BINARYTREE_H
#define FORJOB_BINARYTREE_H

#include <iostream>
#include <fstream>
#include <queue>
#include <stack>
using namespace std;
//freopen("/Users/Alina/ClionProjects/Tree/input/tree","r",stdin);
template <class T>class BinaryTree;
template <class T>
class BinaryTreeNode{
    data;
    BinaryTreeNode<T> * leftchild;
    BinaryTreeNode<T> * rightchild;
    friend class BinaryTree<T>;//设置友元类,可以访问当前类的私有成员
public:
    BinaryTreeNode(d,BinaryTreeNode<T> *l,BinaryTreeNode<T> *r):data(d),leftchild(l),rightchild(r){}
    BinaryTreeNode();

};
template <class T>
class BinaryTree {
    BinaryTreeNode<T> *root;
    int size;
public:
    BinaryTree();
    BinaryTree(BinaryTreeNode<T> *curnode);//用前序扩展树的方式读入,空孩子用#代替
    ~BinaryTree();
    const BinaryTreeNode<T> & GetRoot() const;
    * PreOrderVisit();//前序遍历,非递归
    * MidOrderVisit();//中序遍历,非递归
    * PostOrderVisit();//后序遍历,非递归
    * LevelOrder();//层序遍历,非递归
    * LevelOrderWithLineNum();//层序遍历并按层输出,非递归
    void PrintTree();
    int GetNodeNum();//树中非空的节点个数
    int GetTreeDepth();//获得树深度
private:
    void CreateTree(BinaryTreeNode<T> *&curnode);
    void DropTree(BinaryTreeNode<T> *&curnode);
    void PrintNode(BinaryTreeNode<T> *& curnode);
    int CalculateDepth(BinaryTreeNode<T> *curnode);
};
template <class T>
BinaryTree<T>::BinaryTree() {
//    ifstream cin("/Users/Alina/ClionProjects/Tree/input/tree");
   size 0;
    CreateTree(root);
}
template <class T>
BinaryTree<T>::BinaryTree(BinaryTreeNode<T> *curnode) {
    root = curnode;
}
template <class T>
void BinaryTree<T>::CreateTree(BinaryTreeNode<T> *&curnode) {
    data;
    if(cin>>data){
        if(data != "#") {
            size++;
            curnode = new BinaryTreeNode<T>(data, NULLNULL);
            if (curnode) {
                CreateTree(curnode->leftchild);
                CreateTree(curnode->rightchild);
            }
            else {
                cerr << "tree node initialize error!" << endl;
            }
        }
    }
}

template <class T>
BinaryTree<T>::~BinaryTree() {
    DropTree(root);
}
template <class T>
void BinaryTree<T>::DropTree(BinaryTreeNode<T> *&curnode) {
    if(curnode){
        DropTree(curnode->leftchild);
        DropTree(curnode->rightchild);
        delete curnode;
    }
}

template <class T>
const BinaryTreeNode<T> & BinaryTree<T>::GetRoot() const {
    return *root;
}

template <class T>
BinaryTree<T>::LevelOrder() {//弹出对头节点,如果当前节点有孩子就把孩子入队
    * result = new T[size+1];
    queue<BinaryTreeNode<T>*> q;
    if(!root){
        return NULL;
    }else {
        BinaryTreeNode<T>* cur;
        int i = 0;
        q.push(root);
        while (!q.empty()) {
            cur = q.front();
            if (cur->leftchild) {
                q.push(cur->leftchild);
            }
            if (cur->rightchild) {
                q.push(cur->rightchild);
            }
            q.pop();
            result[i] = cur->data;
            i++;
        }
        return result;
    }
}
template <class T>
TBinaryTree<T>::LevelOrderWithLineNum() {
    //和上面的区别在于需要两个指针记录当前层的最后一个,以及更新下一层的最后一个节点
    //当当前层的最后一个节点被弹出时,该节点的右孩子就是下一层的最后一个节点,此时将当前层last指针指向下一层的last指针
    int depth = GetTreeDepth();
    * result = new T[size+depth];
    queue<BinaryTreeNode<T> *> q;
    if(!root){
        return NULL;
    }else{
        BinaryTreeNode<T> * cur;
        BinaryTreeNode<T> * levellast;
        BinaryTreeNode<T> * templevellast;
        q.push(root);
        levellast = root;
        int i = 0;
        while(!q.empty()){
            cur = q.front();
            result[i] = cur->data;
            i++;
            if(cur->leftchild){
                q.push(cur->leftchild);
                templevellast = cur->leftchild;
            }
            if(cur->rightchild){
                q.push(cur->rightchild);
                templevellast = cur->rightchild;
            }
            if(cur == levellast){
                result[i] = "#";
                i++;
                levellast = templevellast;
            }
            q.pop();
        }
        return result;
    }
}

template <class T>
BinaryTree<T>::PreOrderVisit() {//弹出栈顶节点,如果有右孩子,右孩子进栈,指针指向左孩子
    if(!root){
        return NULL;
    }else{
        * result = new T[size+1];
        stack<BinaryTreeNode<T> *> s;
        BinaryTreeNode<T> * cur;
        s.push(root);
        int i = 0;
        while(!s.empty()){
            cur = s.top();
            s.pop();
            while(cur){
                result[i] = cur->data;
                i++;
                if(cur->rightchild){
                    s.push(cur->rightchild);
                }
                if (cur->leftchild){
                    cur = cur->leftchild;
                }else{
                    cur = NULL;
                }
            }
        }
        return result;
    }
}

template <class T>
BinaryTree<T>::MidOrderVisit() {//不断将当前节点入栈,深入左子树,左不下去时弹出栈顶元素,深入右子树
    if(!root){
        return NULL;
    }else{
        *result = new T[size+1];
        stack<BinaryTreeNode<T>*> s;
        BinaryTreeNode<T> * cur;
        cur = root;
        int i = 0;
        while(cur||!s.empty()){
            while(cur){
                s.push(cur);
                cur = cur->leftchild;
            }
            if(!s.empty()){
                cur = s.top();
                s.pop();
                result[i] = cur->data;
                i++;
                cur = cur->rightchild;
            }
        }
        return result;
    }
}

template <class T>
BinaryTree<T>::PostOrderVisit() {
//节点入栈顺序为父节点,右孩子节点,左孩子节点//出栈的条件:1.当前节点没有孩子.2.上一次弹出的元素和当前节点是父子关系if (!root){    return NULL;}else{    stack<BinaryTreeNode<T>*> s;    BinaryTreeNode<T>* cur,*pre;    T * result = new T[size+1];    cur = root;    int i = 0;    s.push(root);    pre = NULL;    while(!s.empty()){        cur = s.top();        if((cur ->rightchild == NULL && cur->leftchild == NULL) || (pre!=NULL && (pre==cur->leftchild || pre == cur->rightchild))){            s.pop();            result[i++] = cur->data;            pre = cur;        }        else {            if (cur->rightchild != NULL)                s.push(cur->rightchild);            if (cur->leftchild != NULL)                s.push(cur->leftchild);        }    }    return result;}

}
template <class T>
int BinaryTree<T>::CalculateDepth(BinaryTreeNode<T> *curnode) {
    if(!curnode){
        return 0;
    }else{
        int leftdepth = CalculateDepth(curnode->leftchild);
        int rightdepth = CalculateDepth(curnode->rightchild);
        return (leftdepth>rightdepth?leftdepth:rightdepth)+1;
    }
}

template <class T>
void BinaryTree<T>::PrintTree() {
    PrintNode(root);
    cout<<endl;
}
template <class T>
void BinaryTree<T>::PrintNode(BinaryTreeNode<T> *& curnode) {
    if(curnode) {
        cout << curnode->data << " ";
        if(curnode->leftchild){
            PrintNode(curnode->leftchild);
        }
        if(curnode->rightchild){
            PrintNode(curnode->rightchild);
        }
    }

}

template <class T>
int BinaryTree<T>::GetNodeNum() {
    return size;
}

#endif //FORJOB_BINARYTREE_H

main所在.cpp中代码:
#include <iostream>
#include "BinaryTree.h"
#include <stdio.h>
#include <queue>
using namespace std;

int main() {
    freopen("/Users/Alina/ClionProjects/ForJob/input/tree","r",stdin);
    BinaryTree<string> tree;
    string *r ;
    r = tree.PreOrderVisit();
    for(int i=0;i<tree.GetNodeNum();i++){
        cout<<r[i]<<" ";
    }
    cout<<endl;
    r = tree.MidOrderVisit();
    for(int i=0;i<tree.GetNodeNum();i++){
        cout<<r[i]<<" ";
    }
    cout<<endl;
    r = tree.PostOrderVisit();
    for(int i=0;i<tree.GetNodeNum();i++){
        cout<<r[i]<<" ";
    }
    cout<<endl;
    r = tree.LevelOrder();
    for(int i=0;i<tree.GetNodeNum();i++){
        cout<<r[i]<<" ";
    }
    cout<<endl;
    r = tree.LevelOrderWithLineNum();
    for(int i=0;i<tree.GetNodeNum()+tree.GetTreeDepth();i++){
        if(r[i]=="#"){
            cout<<endl;
        }else{
            cout<<r[i]<<" ";
        }
    }
    cout<<endl;
    return 0;
}


0 0
原创粉丝点击