1、树中结点的数目
- 定义功能: count(node)
在node为根结点的树中统计结点数目
树结点数目的计算示例
- count(A)= count(B)+ count(C)+ count(D)+1
2、树的高度
- 定义功能: height(node)
获取node为根结点的树的高度
树的高度计算示例
- height(A)= MAX{ height(B), height(C), height(D) } + 1
3、树的度数
- 定义功能: degree ( node)
获取node为根结点的树的度数
树的度计算示例
- degree(a)= MAX{ degree(B), degree(C), degree(D),3 }
4、编程实验
#ifndef GTREE_H #define GTREE_H #include "Tree.h" #include"GTreeNode.h" #include"Exception.h" namespace DTLib { template < typename T > class GTree : public Tree<T> { protected: GTreeNode<T>* find(GTreeNode<T>* node,const T& value) const { GTreeNode<T>* ret = NULL; if(node != NULL) { if(node->value == value) { return node; } else { for(node->child.move(0);!node->child.end() && (ret == NULL);node->child.next()) //在node子树中查找 { ret = find(node->child.current(),value); //child里数据元素类型是GTreeNode<T>* } } } return ret; } GTreeNode<T>* find(GTreeNode<T>* node,GTreeNode<T>* obj) const { GTreeNode<T>* ret = NULL; if(node == obj) { return node; } else { if(node != NULL) { for(node->child.move(0);!node->child.end() && (ret == NULL);node->child.next()) { ret = find(node->child.current(),obj); } } } return ret; } void free(GTreeNode<T>* node) { if(node != NULL) { for(node->child.move(0);!node->child.end();node->child.next()) { free(node->child.current()); } if(node->flag()) { delete node; } } } void remove(GTreeNode<T>* node,GTree<T>*& ret) { ret = new GTree<T>(); if(ret == NULL) { THROW_EXCEPTION(NoEnoughMemoryException,"No memory to create new tree ..."); } else { if( root() == node) //待删结点就是跟结点 { this->m_root = NULL; } else { LinkList< GTreeNode<T>* >& child = dynamic_cast< GTreeNode<T>* >(node->parent)->child; //child引用指向待删除结点父结点的链表 child.remove(child.find(node)); //在父结点的链表中 将指向(结点的指针)待删孩子 的结点删除 node->parent = NULL; //此子树彻底地离开了树,并没有清除释放 } ret->m_root = node; } } int count(GTreeNode<T>* node) const { int ret = 0; if(node != NULL) { ret = 1; //如果node没有孩子for循环不会执行 返回1 for(node->child.move(0);!node->child.end();node->child.next()) { ret += count(node->child.current()); } } return ret; //如果node为空直接返回0 } int height(GTreeNode<T>* node) const { int ret = 0; if(node != NULL) { for(node->child.move(0);!node->child.end();node->child.next()) { int h = height(node->child.current()); if(ret < h) { ret = h; } } ret = ret + 1; } return ret; } int degree(GTreeNode<T>* node) const { int ret = 0; if(node != NULL) { ret = node->child.length(); //根结点的度 for(node->child.move(0);!node->child.end();node->child.next()) { int d = degree(node->child.current()); //每个孩子的度 if(ret < d) //拿根结点的度和其它结点度比较 { ret = d; } } } return ret; } public: bool insert(TreeNode<T>* node) { bool ret = true; if(node != NULL) { if(this->m_root == NULL) { node->parent = NULL; this->m_root = node; } else { GTreeNode<T>* np = find(node->parent); if( np != NULL ) { GTreeNode<T>* n = dynamic_cast<GTreeNode<T>*>(node); if( np->child.find(n) < 0 ) { np->child.insert(n); } } else { THROW_EXCEPTION(InvalidOperationException,"Invalid parent tree node ..."); } } } else { THROW_EXCEPTION(InvalidParameterException,"Parameter node cannot be NULL ..."); } return ret; } bool insert(const T& value,TreeNode<T>* parent) { bool ret = true; GTreeNode<T>* node = GTreeNode<T>::NewNode(); if(node) { node->value = value; node->parent = parent; insert(node); } else { THROW_EXCEPTION(NoEnoughMemoryException,"No memory to create new tree node ..."); } return ret; } SharedPointer< Tree<T> > remove(const T& value) { GTree<T>* ret = NULL; GTreeNode<T>* node = find(value); if(node == NULL) { THROW_EXCEPTION(InvalidParameterException,"Can not find the node via parameter value ..."); } else { remove(node,ret); } return ret; } SharedPointer< Tree<T> > remove(TreeNode<T>* node) { GTree<T>* ret = NULL; node = find(node); if(node == NULL) { THROW_EXCEPTION(InvalidParameterException,"Parameter node is invalid ..."); } else { remove(dynamic_cast<GTreeNode<T>*>(node),ret); } return NULL; } GTreeNode<T>* find(const T& value) const { return find(root(),value); } GTreeNode<T>* find(TreeNode<T>* node) const { return find(root(),dynamic_cast< GTreeNode<T>* >(node)); } GTreeNode<T>* root() const { return dynamic_cast< GTreeNode<T>* >(this->m_root); } int degree() const { return degree(root()); } int count() const { return count(root()); } int height() const { return height(root()); } void clear() { free(root()); this->m_root = NULL; } ~GTree() { clear(); } }; } #endif // GTREE_H
main.cpp
#include <iostream> #include"GTree.h" using namespace std; using namespace DTLib; int main() { GTree<char> t; GTreeNode<char>* node = NULL; GTreeNode<char> root; root.value = 'A'; root.parent = NULL; t.insert(&root); //将局部对象作为根结点插入 node = t.find('A'); t.insert('B',node); t.insert('C',node); t.insert('D',node); node = t.find('B'); t.insert('E',node); t.insert('F',node); node = t.find('E'); t.insert('K',node); t.insert('L',node); node = t.find('C'); t.insert('G',node); node = t.find('D'); t.insert('H',node); t.insert('I',node); t.insert('J',node); node = t.find('H'); t.insert('M',node); cout<<t.count()<<endl; cout<<t.height()<<endl; cout<<t.degree()<<endl; return 0; }
5、实战预告
To be continued
思考
如何 遍历 GTree (通用树结构)的每一个结点?