一种树的实现

一种树的实现,在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。共同学习

时间: 2024-10-31 14:02:57

一种树的实现的相关文章

种树(贪心)

2151: 种树 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 714  Solved: 397[Submit][Status][Discuss] Description A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编号1到n.并且每个位置都有一个美观度Ai,如果在这里种树就可以得到这Ai的美观度.但由于A城市土壤肥力欠佳,两棵树决不能种在相邻的位置(i

【BZOJ 2151】 2151: 种树 (贪心+堆)

2151: 种树 Description A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编号1到n.并且每个位置都有一个美观度Ai,如果在这里种树就可以得到这Ai的美观度.但由于A城市土壤肥力欠佳,两棵树决不能种在相邻的位置(i号位置和i+1号位置叫相邻位置.值得注意的是1号和n号也算相邻位置!).最终市政府给园林部门提供了m棵树苗并要求全部种上,请你帮忙设计种树方案使得美观度总和最大.如果无法将m棵树苗

雷军:做安卓平板生态 总要有人先种树

文/雷军 不少米粉一直都在呼吁我们做平板,在此之前市场上的Android平板也不少.但为什么小米创业四年后我们才开始做?因为平板是个非常难做的产品. 苹果CEO Tim Cook没少挖苦Android平板.去年他说, iPad占据了平板市场 81%的流量份额,众多Android平板加起来过 19%.前年他甚至还说过,所有的Android平板都在仓库里或者用户的抽屉里吃灰. 从硬件角度看,Android平板并不是很难做.市场上各类Android板满天飞,有的很贵要好几千元,也有很多性能很差的平板便

洛谷P1250种树(贪心)

题目描述 一条街的一边有几座房子.因为环保原因居民想要在路边种些树.路边的地区被分割成块,并被编号成1..N.每个部分为一个单位尺寸大小并最多可种一棵树.每个居民想在门前种些树并指定了三个号码B,E,T.这三个数表示该居民想在B和E之间最少种T棵树.当然,B≤E,居民必须记住在指定区不能种多于区域地块数的树,所以T≤E-B+l.居民们想种树的各自区域可以交叉.你的任务是求出能满足所有要求的最少的树的数量. 写一个程序完成以下工作: 输入输出格式 输入格式: 第一行包含数据N,区域的个数(0<N≤

1768 种树 3

1768 种树 3 2012年 时间限制: 2 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 为了绿化乡村,H村积极响应号召,开始种树了. H村里有n幢房屋,这些屋子的排列顺序很有特点,在一条直线上.于是方便起见,我们给它们标上1~n.树就种在房子前面的空地上. 同时,村民们向村长提出了m个意见,每个意见都是按如下格式:希望第li个房子到第ri个房子的房前至少有ci棵树. 因为每个房屋前的空地面积有限,所以每个房屋前

[swustoj 183] 种树

种树(0183) 问题描述 Aconly有一块矩形的地,因为这块地里有很多石头,耕作很不方便,所以他打算在这块地上种一些果树.这块地用一个只含‘#’和‘*’的N*M的矩阵来表示,‘#’表示泥土,‘*’表示石头.当然有石头的地方是不能种树的,而且任意两棵树之间不能离得太近,表现在矩阵中就是不能上.下.左.右.左上.右上.左下.右下八个方向相邻.你的任务就是帮助Aconly算出这块地最多可以种多少棵树. 输入 有多组测试数据.每组测试数据以两个整数N和M开头,随后有N行只含‘#’和‘*’的字符,每行

[Data Structure] 数据结构中各种树

数据结构中有很多树的结构,其中包括二叉树.二叉搜索树.2-3树.红黑树等等.本文中对数据结构中常见的几种树的概念和用途进行了汇总,不求严格精准,但求简单易懂. 1. 二叉树 二叉树是数据结构中一种重要的数据结构,也是树表家族最为基础的结构. 二叉树的定义:二叉树的每个结点至多只有二棵子树(不存在度大于2的结点),二叉树的子树有左右之分,次序不能颠倒.二叉树的第i层至多有2i-1个结点:深度为k的二叉树至多有2k-1个结点:对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=

BZOJ2151 种树

Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 565  Solved: 310[Submit][Status][Discuss] Description A 城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编号1到 n.并且每个位置都有一个美观度Ai,如果在这里种树就可以得到这Ai的美观度.但由于A城市土壤肥力欠佳,两棵树决不能种在相邻的位置(i号位置和 i+

1653 种树 2

1653 种树 2 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 一条街的一边有几座房子.因为环保原因居民想要在路边种些树.路边的地区被分割成块,并被编号为1…n.每个块的大小为一个单位尺寸并最多可种一裸树.每个居民想在门前种些树并指定了三个号码b,e,t.这三个数表示该居民想在b和e之间最少种t棵树.当然,b≤e,居民必须保证在指定地区不能种多于地区被分割成块数的树,即要求T≤ e-b+1.允许居民想种树的各自区

[COGS1862]种树 解题报告

[问题描述] A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编号1到n.并且每个位置都有一个美观度Ai,如果在这里种树就可以得到这Ai的美观度.但由于A城市土壤肥力欠佳,两棵树决不能种在相邻的位置(i号位置和i+1号位置叫相邻位置.值得注意的是1号和n号也算相邻位置!). 最终市政府给园林部门提供了m棵树苗并要求全部种上,请你帮忙设计种树方案使得美观度总和最大.如果无法将m棵树苗全部种上,给出无解信息.