树——通用树结点的清除

1,树是一种数据结构,用来存储容器,因此它可以用来看做一种容器类型;既可以向容器中插入东西,也可以将容器中的东西倒出来;

2,清除操作的定义:

1,void clear():

1,将树中的所有结点清除(释放堆中的结点);

3,树中数据元素的清除:

1,递归清除;

4,清除操作功能的定义:

1,free(node)

1,清除 node 为根结点的树;

2,释放树中的每一个结点;

  2,功能函数代码实现:

 1    /* 清除 node 树的根结点 */
 2     void free(GTreeNode<T>* node)
 3     {
 4         if( node != NULL )  // 非空树,结点的父结点为空和结点指向空是截然不同的,一个是根结点,一个是空树
 5         {
 6             for(node->child.move(0); !node->child.end(); node->child.next())
 7             {
 8                 free(node->child.current());  // 每个孩子执行清除操作
 9             }
10
11             if( node->flag() ) // 是否来自堆空间,有些结点直接在栈上申请了,没有用 insert() 函数申请
12             {
13                 delete node;  // 删除根结点,只有堆中的对象才能 delete, 否则其他对象在其生命周期是不需要在代码里面来管理的,否则崩溃
14             }
15         }
16   }

5,清除 clear() 函数代码的实现:

1     void clear()
2     {
3         free(root());
4         this->m_root = NULL;
5         m_queue.clear();  // 树里面每个元素都没有了,所以也要清除队列里面的数据元素
6     }

6,树中的结点可能来源于不同的存储空间,如何判断指针指向的结点对象是堆空间中的结点并释放?

1,问题分析:

1,单凭内存地址很难准确判断具体的存储区域;

2,只有堆空间的内存需要主动释放(delete);

1,堆空间中的内存通过 new 来的,可以在 new 一个对象时,标记一个对象,依据标记来 delete;

3,清除操作时只要对堆空间中的结点进行释放;

2,解决方案:工厂模式

1,在 GTreeNode 中增加保护成员变量 m_flat;

1,增加标记;

2,将 GTreeNode 中的 operator new 重载为保护成员函数;

1,意味着在外部不能用 new 操作符创建堆空间中的结点;

3,提供工厂方法 GTreeNode<T>* NewNode();

1,NewNode() 是公有静态的,返回堆里面的一个结点;

2,在外部可以用它创建堆空间的结点;

3,这就是工厂方法;

4,在工厂方法中 new 新结点并将 m_flag 设置为 true;

3,树结点的工厂模式示例:

1,也就是禁止外界 new (因为外界 new 不会标记)的同时让外界或内部用 NewNode() 并标记  m_flag;

7,工程模式代码实现(具体参见博文“树——树的定义与操作”中 15.1 和“树——通用树的存储结构与结点实现”中 7.1的内容):

 1     protected:  // 从两个子类中重构而来;减少代码冗余
 2     bool m_flag;  // 结点是否申请自堆空间的标志,第一步
 3
 4     void* operator new(unsigned int size) throw()  // new 不能够在外部调用了,统一路径,第二步
 5     {
 6         return Object::operator new(size);
 7     }
 8
 9 public:
10     T value;  // 存储数据
11     GTreeNode<T>* parent;  // 每个结点包含指向父结点的指针,向上是线性数据结构(链表)
12
13     GTreeNode()
14     {
15         m_flag = false;  // 构造函数将堆空间申请标志置为 false; 第四步
16         parent = NULL;
17     }
18
19     static GTreeNode<T>* NewNode() // 工厂模式,第三步
20     {
21         GTreeNode<T>* ret = new GTreeNode<T>();
22         if( ret != NULL )  // 申请堆空间成功
23         {
24             ret->m_flag = true;
25         }
26         return ret;
27     }
28
29     bool flag()  // 堆空间的标志; 重构而来
30     {
31         return m_flag;
32     }

8,小结:

1,清除操作用于销毁树中的每个结点;

2,销毁结点时需要决定是否释放对应的内存空间;

1,之前的顺序结构没有销毁结点的考虑是因为它们的结点不是单独的类,外界不能够定义;

3,工厂模式可用于“定制”堆空间中的结点;

原文地址:https://www.cnblogs.com/dishengAndziyu/p/10925272.html

时间: 2024-10-24 09:39:19

树——通用树结点的清除的相关文章

树——通用树的存储结构与结点实现

1,上篇博文介绍了树的定义和相关概念定义,本节课创建树对象和树结点对象: 2,课程目标: 1,完成树和结点的存储结构设计: 1,没有树结点,就没有树,同生死: 3,设计要点: 1,GTree 为通用树结构,每个结点可以存在多个后继结点: 2,GTreeNode 能够包含任意多指向后继结点的指针: 3,实现树结构的所有操作(增,删,查,等): 1,抽象类只用包含功能函数,具体的对象才包含成员变量和实现功能函数: 4,GTreeNode 的设计与实现: 1,组合单链表类,因为要包含任意多指向结点的指

树——通用树到二叉树的转换

1,已经创建了通用树结构,有必要创建另一种树结构吗? 2,简化树就直接减少结点中孩子的数量,但是这样树还能通用吗? 3,通用树结构的回顾: 1,双亲孩子表示法: 1,每个结点都有一个指向双亲的指针: 2,每个结点都有若干个指向其孩子的指针: 4,另一种树结构模型: 1,孩子兄弟表示法: 1,每个结点都有一个指向其第一个孩子的指针: 2,每个结点都有一个指向其第一个右兄弟的指针: 1,孩子兄弟表示法可以描述普通的树型结构,因为通过根结点可以访问到这一个树形结构的每一个结点: 5,孩子兄弟表示法的特

树——通用树的层次遍历

1,为何及如何按层次遍历通用树中的每一个数据元素? 1,通用树结构是一种容器类型的树结构,其用来装数据元素,所以应该提供一种方法来遍历树中的每一个数据结构: 2,往下分析: 2,当前的事实: 1,树是非线性的数据结构,树的结点没有固定的编号方式: 1,也就不能像链表一样统一编号来访问: 3,新的需求: 1,为通用树结构提供新的方法,快速遍历每一个结点: 4,设计思路(游标): 1,在树中定义一个游标(GTreeNode<T>*): 2,遍历开始前将游标指向根结点(root()): 3,获取游标

数据结构(12)_树的概念及通用树的实现

1.树的定义与操作 1.1.树的相关定义 1.树的定义 树是一种非线性的数据结构,右n(n>=0)个结点组成的有限集合,如果n=0,称为空树,如果n>0,则: 有一个特定的结点被称之为跟结点(root),根结点只有直接后继,没有前驱, 除根结点外的其他结点划分为m(m>=0)个互不相交的有限集合T0,T1...Tm-1,每一个集合又是一颗子树,并称之为跟的子树.树的示例如下: 2.树中度的概念 树的结点包含一个数据及如果指向子树的分支,结点拥有的子树数目称为结点的度(度为0的结点称为叶结

CSS规则树和HTML的DOM树合成渲染树时渲染结点与选择器链的匹配

在浏览器内核(排版引擎)CSS规则树和HTML的DOM树合成渲染树的时候,会涉及到渲染树的位置属性的问题,因为其位置属性将通过CSS选择器链的优先级来决定,而渲染树的某个结点可能会同时满足多个选择器链,这时候就要通过选择器的优先级来完成属性的赋值. 在这个地方,我仅仅处理了几个简单的选择器情况:{(.class)     (#id)       (element)      (#id,.class,elememt)      (#id>.class)        (#id element)  

16.输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印

转载请注明出处:http://www.cnblogs.com/wuzetiandaren/p/4261605.html 声明:现大部分文章为寻找问题时在网上相互转载,此博是为自己做个记录记录,方便自己也方便有类似问题的朋友,本文的思想也许有所借鉴,但源码均为本人实现,如有侵权,请发邮件表明文章和原出处地址,我一定在文章中注明.谢谢. 题目:输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印. 题目分析:可以用一个LinkedList的数据结构模拟队列来完成此操作.传入树

剑指Offer——Trie树(字典树)

剑指Offer--Trie树(字典树) Trie树 Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优点是:最大限度地减少无谓的字符串比较,查询效率比哈希表高. Trie的核心思想是空间换时间.利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的. Trie树也有它的缺点,Trie树的内存消耗非常大.当然,或许用左儿子右兄弟的方法建树的话,可能会好点.可见,优

B树(B+树) 学习总结

一,B树的定义及介绍 为什么会有B树? 熟悉的树的结构有二叉树查找树或者平衡二叉树……平衡二叉树保证最坏情况下各个操作的时间复杂度为O(logN),但是为了保持平衡,在插入或删除元素时,需要进行旋转啊...一系列操作,因此实现起来比较复杂.而对于二叉查找树,基本操作在最坏情况下会出现O(N)的时间复杂度.总之,这些树都是针对于内存中的数据操作,它们每个结点最多只有两个孩子,当数据量大时(结点数目很多),就会导致树很高.但由于基本操作(查找元素.插入元素)都是在内存中实现,因此,树高点也就没有太大

[BZOJ3110] [Zjoi2013] K大数查询 (树套树)

Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少. Input 第一行N,M 接下来M行,每行形如1 a b c或2 a b c Output 输出每个询问的结果 Sample Input 2 5 1 1 2 1 1 1 2 2 2 1 1 2 2 1 1 1 2 1 2 3 Sample Output 1 2 1 HINT [