树-左孩子右兄弟

左孩子右兄弟表示法,原理和孩子表示法差不多。主要仍然是输入的处理,如果不使用广义表,就会简单很多

/*  Author : Moyiii
 *  Mail:  [email protected]
 *  树,左孩子,右兄弟表示法实现,只实现了几个简单的功能
 *  复杂功能根据需要可以自己去实现
 *  全部封装会很麻烦
 *  仅作学习之用,当然如果
 *  你想拿去用,随你好啦。
*/
#include<iostream>
#include<queue>
#include<string>
using namespace std;

#define MAX_TREE_DEGREE 100

//int created = 0;
//int deleted = 0;

class TreeNode
{
public:
    TreeNode()
    {
        sib = child = NULL;
    }
    char data;
    TreeNode* child;
    TreeNode* sib;
};



class LinkTree
{
public:
    LinkTree();
    void input(TreeNode *&node,string s);
    void clear(TreeNode *node);
    void print(TreeNode *node);
    TreeNode *root;
    ~LinkTree();
private:
    void getStr(string &pre, string &rest);
};


LinkTree :: ~LinkTree()
{
    clear(root);
}

LinkTree :: LinkTree()
{
    root = NULL;
}


void LinkTree :: clear(TreeNode *node)
{
    if(node == NULL)
    {
        return;
    }
    else
    {
        if(node->child != NULL)
        {
            TreeNode *temp = node->child;
            while(temp != NULL)
            {
                TreeNode *p = temp;
                temp = temp->sib;
                clear(p);
            }
        }
        delete node;
        //deleted++;
        return;
    }
}

//获取rest的第一个子串,rest为逗号后的内容,这个函数来自于广义表
//可以到严书广义表章节中找到这个函数的原型
void LinkTree :: getStr(string &pre, string &rest)
{
    int count = 0;
    int i = 0;
    while(i < rest.length() && rest[i] != ',' || count != 0)
    {
        if(rest[i] == '(')
        {
            count++;
        }
        else if(rest[i] == ')')
        {
            count--;
        }
        i++;
    }
    pre = rest.substr(0,i);
    if(i != rest.length())
    {
        rest = rest.substr(i+1,rest.length() - i);
    }
    else
    {
        rest = "";
    }
    return;
}

//类似广义表的做法。这就是个广义表其实
void LinkTree :: input(TreeNode *&node, string s)
{
    node = new TreeNode;
    node->data = s[0];
    //created++;
    if(s.length() == 1)
    {
        return;
    }
    else
    {
        int num = 0;
        s = s.substr(2,s.length() - 3);
        //第一个孩子
        string pre;
        getStr(pre,s);
        input(node->child,pre);
        TreeNode *temp = node->child;
        //孩子的兄弟们
        while(s.length() != 0)
        {
            getStr(pre,s);
            input(temp->sib,pre);
            temp = temp->sib;
        }
    }
}

//层次打印,用的是层次遍历的方法。思路应该很简单
void LinkTree :: print(TreeNode *node)
{
    if(node == NULL)
    {
        return;
    }
    else
    {
        queue<TreeNode*> q;
        q.push(node);
        while(!q.empty())
        {
            TreeNode *temp = q.front();
            q.pop();
            cout << temp->data << "(";
            if(temp->child != NULL)
            {
                cout << temp->child->data;
                q.push(temp->child);
                temp = temp->child->sib;
                while(temp != NULL)
                {
                    q.push(temp);
                    cout << "," << temp->data;
                    temp = temp->sib;
                }
            }
            cout << ")";
            cout << endl;
        }
    }
    return;
}

int main()
{
    LinkTree t;
    string s = "R(A(D,E),B,C(F(G,H,K)))";
    t.input(t.root, s);
    t.print(t.root);
    cout << endl;
    t.clear(t.root);
    //cout << "created:" << created << endl;
    //cout << "deleted:" << deleted << endl;
    return 0;
}


你可能感兴趣的:(数据结构,树,左孩子右兄弟)