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

c++中用模板类建立树的抽象结构要注意c++中的类模板不能实现分离编译,即定义在.h文件,实现在.cpp文件,因此要将定义和实现都写在.h文件中
原因见: http://blog.csdn.net/pongba/article/details/19130


输入的树形为:

c++二叉树的建立、前序中序后序深搜、宽搜、宽搜带行号_第1张图片

输入文件内容为:
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  
#include  
#include  
#include  
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  
#include  "BinaryTree.h"
#include  
#include  
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         cout <<r[i] << " ";
    }
    cout <<endl;
    r = tree.MidOrderVisit();
    for( int i= 0;i         cout <<r[i] << " ";
    }
    cout <<endl;
    r = tree.PostOrderVisit();
    for( int i= 0;i         cout <<r[i] << " ";
    }
    cout <<endl;
    r = tree.LevelOrder();
    for( int i= 0;i         cout <<r[i] << " ";
    }
    cout <<endl;
    r = tree.LevelOrderWithLineNum();
    for( int i= 0;i         if(r[i] == "#"){
            cout <<endl;
        } else{
            cout <<r[i] << " ";
        }
    }
    cout <<endl;
    return  0;
}


你可能感兴趣的:(c++)