双标记位先根次序构建树

来源:互联网 发布:c语言中rand函数 编辑:程序博客网 时间:2024/05/18 13:29

利用带双标记的先根次序信息,来构造左孩子右兄弟方式表示的树。

#include <iostream>#include <stack>//#include "TreeNode.h"using namespace std;const int N = 10;                   //结点数量template <class T> class Tree;      //声明树类// 带“双标记”的先根次序 结点类template <class T>class DualTagTreeNode  {public:    T info;                         //树结点信息    int ltag;                       //左标记    int rtag;                       //右标记    DualTagTreeNode() {};           //构造函数    virtual ~DualTagTreeNode() {};  //析构函数};// 树结点类的ADTtemplate <class T>class TreeNode  {friend class Tree<T>;private:    T m_Value;                      //树结点的值    TreeNode<T>*    pChild;         //左子结点    TreeNode<T>*    pSibling;       //右兄弟结点public:    TreeNode() {};    TreeNode(const T &value) {m_Value = value; pChild = NULL; pSibling = NULL;};    T Value() {return m_Value;};                     // 获得结点的信息    TreeNode<T> *LeftMostChild() {return pChild;};   // 返回第一个左子树    TreeNode<T> *RightSibling() {return pSibling;};  // 返回第一个右兄弟    void setValue(T &value) {m_Value = value;};      //设置结点的值    void setChild(TreeNode<T> *pointer) {pChild = pointer;};        //设置左孩子    void setSibling(TreeNode<T> *pointer) {pSibling = pointer;};    //设置右孩子};// 树类ADT,只写出了相关的变量及函数template <class T>class Tree  {private:    TreeNode<T> *root;    TreeNode<T> *getParent(TreeNode<T> *root, TreeNode<T> *current);public:    Tree() {root = NULL;};    Tree(DualTagTreeNode<T> *nodeArray, int count); //带双标记先根次序构造算法    TreeNode<T> *getRoot() {return root;};          //返回树中的根结点    void Visit(T Value) {cout << Value;};           //访问    void RootFirstTraverse(TreeNode<T> *root);      //先根次序周游,作为测试使用};// 函数功能:带双标记先根次序构造算法template <class T>Tree<T>::Tree(DualTagTreeNode<T>* nodeArray, int count)  {//利用带双标记位的先根次序表示的树构造左孩子右兄弟方式表示的树    //使用STL中的stack    using std::stack;    stack<TreeNode<T>* > aStack;    //准备建立根结点    TreeNode<T>* pointer = new TreeNode<T>;    root=pointer;    //处理一个结点    for(int i = 0;i < count-1;i++) {        pointer->setValue(nodeArray[i].info);        if(nodeArray[i].rtag == 0)            aStack.push(pointer);                   //将结点压栈        else            pointer->setSibling(NULL);              //右兄弟设为空        TreeNode<T>* temppointer = new TreeNode<T>;        if(nodeArray[i].ltag == 0)            pointer->setChild(temppointer);        else {            pointer->setChild(NULL);                //左孩子设为空            pointer = aStack.top();              aStack.pop();            pointer->setSibling(temppointer);        }        pointer = temppointer;    }    //处理最后一个结点    pointer->setValue(nodeArray[count-1].info);    pointer->setChild(NULL);    pointer->setSibling(NULL);}// 函数功能:先根深度遍历template <class T>void Tree<T>::RootFirstTraverse(TreeNode<T> *root)  {    while (root != NULL)  {        Visit(root->Value());        RootFirstTraverse(root->LeftMostChild());        root = root->RightSibling();    }}// 函数功能:显示森林结构.图6.5(a)所示的森林void DisplayTree()  {    cout << "      A              G      \n";    cout << "   /  |  \\         /   \\   \n";    cout << "  B   C    D      H     I   \n";    cout << "     / \\          |         \n";    cout << "    E   F         J         \n";    cout << endl;    cout << "rtag =  0 , there is    a right sibling" << endl;    cout << "rtag =  1 , there isn't a right sibling" << endl;    cout << "ltag =  0 , there is    a left child" << endl;    cout << "ltag =  1 , there isn't a left child" << endl << endl;}// 函数功能:显示森林结构的带双标记先根次序表示void DisplayNode(char *Info, int *nRtag, int *nLtag)  {    if (Info != NULL)  {        cout << "info   ";        for (int i = 0; i < N; i ++)            cout << Info[i] << " ";        cout << endl;    }    if (nRtag != NULL)  {        cout << "rtag   ";        for (int i = 0; i < N; i ++)            cout << nRtag[i] << " ";        cout << endl;    }    if (nLtag != NULL)  {        cout << "ltag   ";        for (int i = 0; i < N; i ++)            cout << nLtag[i] << " ";        cout << endl;    }}// 函数功能:周游树,在这里只列举一种(先根次序)void Traverse(Tree<char> *tree)  {    cout << "FirstRoot traverse:  ";    tree->RootFirstTraverse(tree->getRoot()); // 先根深度优先周游    cout << endl;}int main()  {    // 显示森林结构    DisplayTree();    // 带双标记先根次序构造算法,图6.5(a)所示的森林的带双标记位的先根次序表示为例    char strInfo[N] = {'A', 'B', 'C', 'E', 'F', 'D', 'G', 'H', 'J', 'I'};    int nRtag[N] = {0, 0, 0, 0, 1, 1, 1, 0, 1, 1};    int nLtag[N] = {0, 1, 0, 1, 1, 1, 0, 0, 1, 1};    cout << "Dualtag_FirstRoot create tree." << endl;       //打印带双标记位的先根次序表示    DisplayNode(strInfo, nRtag, nLtag);    DualTagTreeNode<char> *nodeArray = new DualTagTreeNode<char>[N];    for (int i = 0; i < N; i ++)  {                //设置带双标记位的先根次序结点类        nodeArray[i].info = strInfo[i];        nodeArray[i].rtag = nRtag[i];        nodeArray[i].ltag = nLtag[i];    }    Tree<char> aTree(nodeArray, N); // 建树    Traverse(&aTree);               // 周游树,结果:ABCEFDGHJI    return 0;}


0 0
原创粉丝点击