现在的位置: 首页 > 综合 > 正文

二叉树—–静态二叉链表(游标)—–建立(先序)+遍历(7种)

2013年09月15日 ⁄ 综合 ⁄ 共 3618字 ⁄ 字号 评论关闭
//file:BTtree.h
#ifndef _BTTREE_H_HUMING_INCLUDE_
#define _BTTREE_H_HUMING_INCLUDE_
#include<iostream>
#include<queue>
#include<stack>
#define maxlen 1002
using namespace std;
template <class T>
class treenode
{
public:
    treenode():lchild(-1),rchild(-1) {}; //构造函数
    ~treenode() {}; //析构函数
    T  data;
    int lchild,rchild;
};
template <class T>
class BTtree
{
public:
    BTtree():root(-1),nodenum(0) {}; //构造函数,树为空,开始的时候没有元素
    ~BTtree() {};//析构
    void pre_create();  //建立二叉树
    int Lchild(int  t);//返回右儿子位置
    int Rchild(int t);  //返回儿子位置
    T elements(int t);  //返回下标所对应元素
    bool Isempty();  //判空
    int return_root();  //返回根节点下标
    void pre_order(int t);//先序递归
    void in_order(int t);//中序递归
    void post_order(int t);//后序递归
    void nrec_pre_order(int t);//先序非递归
    void nrec_in_order(int t);//中序非递归
    void nrec_post_order(int t);//后序非递归
    void level_order(int t);//层序遍历
    //几个遍历函数@
private:
    treenode<T> element[maxlen];//二叉树的节点
    int root;//根节点的下标
    int nodenum;//存储所用空间
    int insert(); //用来插入
};
template <class T>
int BTtree<T>::Lchild(int t)
{
  return element[t].rchild;
}
template <class T>
int BTtree<T>::Rchild(int t)
{
    return element[t].lchild;
}
template<class T>
T BTtree<T>::elements(int t)
{
    return element[t].data;
}
template <class T>
int  BTtree<T>::return_root()
{
    return root;
}
template <class T>
void BTtree<T>::pre_create()
{
    root=insert();
}
template<class T>
int BTtree<T>::insert()
{
    T ch;
    cin >> ch;
    int t=nodenum;
    //把最后一个节点的下标赋给t,要知道每个节点都是一二叉树,这是建立二叉树的基础
    if(ch=='#') t=-1;
    else
    {
        nodenum++;//相当于链表中的开辟新的节点
        element[t].data=ch;
        element[t].lchild=insert();
        element[t].rchild=insert();
    }
    return t;//返回二叉树根节点的下标
}
template <class T>
void BTtree<T>::pre_order(int t)
{
    if(t!=-1)
    {
        cout << element[t].data;
        pre_order(element[t].lchild);
        pre_order(element[t].rchild);
    }
}

template <class T>
void BTtree<T>::in_order(int t)
{
    if(t!=-1)
    {
        in_order(element[t].lchild);
        cout << element[t].data;
        in_order(element[t].rchild);
    }
}
template <class T>
void BTtree<T>::post_order(int t)
{
    if(t!=-1)
    {
        post_order(element[t].lchild);
        post_order(element[t].rchild);
        cout << element[t].data;
    }
}
template <class T>
void BTtree<T>::nrec_pre_order(int t)
{
    stack<int> s;
    while(t!=-1||!s.empty())//循环到栈空而且树为空
    {
        while(t!=-1)//如果树不为空一直向下访问,左走一步
        {
            cout << element[t].data;
            s.push(t);
            t=element[t].lchild;
        }
        if(!s.empty())
        {
            t=s.top();
            s.pop();//取栈顶并出栈
            t=element[t].rchild; //右走一步
        }
    }
}
template <class T>
void BTtree<T>::nrec_in_order(int t)
{
    stack<int> s;
    while(t!=-1||!s.empty())//循环到栈空而且树为空
    {
        if(t!=-1)//树不空压栈左走一步
        {
            s.push(t);
            t=element[t].lchild;
        }
        else//树空(这时候在左儿子上),出栈访问父节点,右走【中序】
        {
            t=s.top();
            s.pop();
            cout << element[t].data;
            t=element[t].rchild;
        }
    }
}
template <class T>
void BTtree<T>::nrec_post_order(int t)
{
    struct STACK
    {
        int  tree,flag;
    } S[maxlen];
    int top=maxlen;//设置一个倒过来的顺序栈(受书上影响,我喜欢倒着用,看个人习惯~~)
    int temp;
    temp=t;
    while(temp!=-1||top!=maxlen)//循环到栈空和树空
    {
        if(temp!=-1)//树不空,入栈并标记为第一次访问,左走
        {
            S[--top].tree=temp;
            S[top].flag=1;
            temp=element[temp].lchild;
        }
        else//树空
        {
            if(S[top].flag==2)//如果栈顶元素是已经两次访问过的,那么出栈访问输出
            {
                t=S[top++].tree;
                cout << element[t].data;
            }
            else//如果栈顶访问过一次,那么标记为第二次访问,右走
            {
                S[top].flag=2;
                temp=element[S[top].tree].rchild;
            }
        }
    }
}
template <class T>
void BTtree<T>::level_order(int  t)
{
    //层序有先进先出的特点
    queue<int> q;
    int p;
    if(t==-1)  return;
    q.push(t);
    while(!q.empty())//访问到队列空
    {
        p=q.front();
        cout << element[p].data;//出队访问
        if(element[p].lchild!=-1)
            q.push(element[p].lchild);//左树不空,入队
        if(element[p].rchild!=-1)
            q.push(element[p].rchild);//右树不空,入队
        q.pop();
    }
}
#endif

//main.cpp
#include  "BTtree.h"
int main()
{
    BTtree<char> test;
    test.pre_create();
    test.pre_order(test.return_root());
    cout << endl;
    test.in_order(test.return_root());
    cout << endl;
    test.post_order(test.return_root());
    cout << endl;
    test.nrec_pre_order(test.return_root());
    cout << endl;
    test.nrec_in_order(test.return_root());
    cout << endl;
    test.nrec_post_order(test.return_root());
    cout << endl;
    test.level_order(test.return_root());
    cout << endl;
    return 0;
}
//ABDH##I##E##CF#J##G##
//ABDHIECFJG
//HDIBEAFJCG
//HIDEBJFGCA
//ABDHIECFJG
//HDIBEAFJCG
//HIDEBJFGCA
//ABCDEFGHIJ

抱歉!评论已关闭.