一种树的实现

一种树的实现,在Qt界面的一个例子上看到的,把在VC++6.0上实现并写成模板

#include <vector>
#include <iostream>
#include <stack>
#include <queue>
#include <string>
using namespace std;

template<typename T>
class TreeItem
{
public:
    TreeItem(T data, TreeItem<T> *parent = 0);
    ~TreeItem();
    TreeItem<T> *child(int number);
    int childCount() const;//孩子的个数
    int childNumber() const;//当前节点是第几个孩子
    bool insertChildren(int position, T data);//插入孩子
    bool insertChildren(int position, TreeItem<T> *p);//重载
    TreeItem<T> *parent();//获取父亲
    bool removeChildren(int position);//删除一个孩子
    TreeItem<T>* rihghtbrother();//获取右兄弟
    bool swapchildren(int first, int second);//交换孩子的顺序
    T data();
private:
    T Data;
    vector<TreeItem<T>*> childItems;
    TreeItem<T> *parentItem;
};

template<typename T>
TreeItem<T>::TreeItem(T data, TreeItem<T> *parent)
{
    parentItem = parent;
    Data = data;
}

template<typename T>
TreeItem<T>::~TreeItem()
{
    for(int i=0; i<childItems.size(); i++)
    delete childItems[i];
}

template<typename T>
TreeItem<T>* TreeItem<T>::child(int number)
{
    if(number<0 || number>=childItems.size())
        return NULL;
    return childItems[number];
}

template<typename T>
int TreeItem<T>::childCount() const
{
    return childItems.size();
}

template<typename T>
int TreeItem<T>::childNumber() const
{
    if (parentItem)
        for(int i=0;i<parentItem->childItems.size();i++)
            if(this == parentItem->childItems[i])
                return i;
    return 0;
}

template<typename T>
bool TreeItem<T>::insertChildren(int position, T data)
{
    if(position<0 || position>childItems.size())
        return false;
    TreeItem<T> *item = new TreeItem<T>(data,this);
    vector<TreeItem<T>*>::iterator iter = childItems.begin();
    childItems.insert(iter+position, item);
    return true;
}

template<typename T>
bool TreeItem<T>::insertChildren(int position, TreeItem<T> *p)
{
    if(position<0 || position>childItems.size())
        return false;
    vector<TreeItem<T>*>::iterator iter = childItems.begin();
    childItems.insert(iter+position, p);
    return true;
}
    

template<typename T>
TreeItem<T>* TreeItem<T>::parent()
{
    return parentItem;
}

template<typename T>
bool TreeItem<T>::removeChildren(int position)
{
    if (position < 0 || position>=childItems.size())
        return false;
    delete childItems[position];
    return true;
}

template<typename T>
TreeItem<T>* TreeItem<T>::rihghtbrother()
{
    TreeItem *p = this->parentItem;
    if(p && p->childCount()>(this->childNumber()+1))
        return p->child(childNumber()+1);
    return NULL;
}

template<typename T>
bool TreeItem<T>::swapchildren(int first, int second)
{
    if(first==second)return true;

    int count = childItems.size();
    if (first < 0 || first >= count)
        return false;
    if (second < 0 || second >= count)
        return false;
    TreeItem<T> *p = childItems[first];
    childItems[first] = childItems[second];
    childItems[second] = p;
}

template<typename T>
T TreeItem<T>::data()
{
    return Data;
}


///////////////////////////////////////////////////////////////////
/// \brief The Tree class
template<typename T>
class Tree
{
public:
    Tree(TreeItem<T> *root){rootItem=root;}
    void Previsit();
    void Postvisit();//和前序遍历一样,只是"操作"在出栈时进行
    void Levelvisit();
    ////operations else...........
private:
    TreeItem<T> *rootItem;
};

template<typename T>
void Tree<T>::Previsit()
{
    stack<TreeItem<T>*> st;
    TreeItem<T>* q= rootItem;
    st.push(q);
    cout<<q->data()<<" ";
    while(q->childCount())
    {
        q = q->child(0);
        st.push(q);
        cout<<q->data()<<" ";
    }
    while(!st.empty())
    {
        q = st.top();
        st.pop();
  //      cout<<q->data()<<" ";
        if(q->rihghtbrother())
        {
            q = q->rihghtbrother();
            st.push(q);
            cout<<q->data()<<" ";
            while(q->childCount())
            {
                q = q->child(0);
                st.push(q);
                cout<<q->data()<<" ";
            }
        }
    }
}

template<typename T>
void Tree<T>::Levelvisit()
{
    queue<TreeItem<T>*> que;
    TreeItem<T>* q= rootItem;
    que.push(q);
    while(!que.empty())
    {
        q = que.front();
        que.pop();
        cout<<q->data()<<" ";
        for(int i=0; i<q->childCount(); i++)
            que.push(q->child(i));
    } 
}

int main()
{
    TreeItem<string> *rootItem = new TreeItem<string>("root",NULL);
// 实际使用时用第二个重载的insertChildren更实用。。。。。。。。。。。。 rootItem
->insertChildren(0,"A"); rootItem->insertChildren(1,"B"); rootItem->insertChildren(2,"C"); rootItem->insertChildren(3,"D"); rootItem->child(0)->insertChildren(0,"A1"); rootItem->child(0)->insertChildren(1,"A2"); rootItem->child(1)->insertChildren(0,"B1"); rootItem->child(1)->insertChildren(1,"B2"); rootItem->child(1)->insertChildren(2,"B3"); rootItem->child(3)->insertChildren(0,"D1"); // rootItem->swapchildren(0,2); Tree<string> tree(rootItem); // tree.Previsit(); tree.Levelvisit(); return 0; }

 

在TreeItem中应该用链表来管理孩子的指针会好点,代码编译通过,但不知道还有没有Bug。共同学习

posted on 2015-08-09 11:19  赵华  阅读(309)  评论(0编辑  收藏  举报

导航