树——通用树结点的插入

1,通用树中的插入操作是以查找操作为基础的;

2,插入的方式:

       1,插入新结点:

              1,bool insert(TreeNode<T>* node)

       2,插入数据元素:

              1,bool insert(const T& value, TreeNode<T>* parent)

             

3,如何指定新结点在树中的位置?

 

       1,问题分析:

              1,树是非线性的,无法采用下标的形式定位数据元素;

              2,每一个树结点都有唯一的前驱结点(父结点);

              3,因此,必须先找到前驱结点,才能完成新结点的插入;  

4,新结点的插入:

 

       1,插入操作不是递归实现的;

       2,插入操作在查找操作帮助下是非常容易实现的;

       3,要插入结点,只用关注父结点中的关于子结点部分(child 链表),至于插入结点的 parent 和 value 不是自己维护的范围,已经被插入者维护好了;

  4,代码实现:

 1    /* 实现从 Tree<T> 中继承而来的纯虚函数没有插入操作的时候,无法构建一棵树插入操作是构建树的唯一操作,非递归*/
 2     bool insert(TreeNode<T>* node)
 3     {
 4         bool ret = true;
 5 
 6         if( node != NULL )  // 不能插入空结点
 7         {
 8             if( this->m_root == NULL )  // 插入的树是空树
 9             {
10                 node->parent = NULL;  // 新结点是根结点,树中通过插入结点的父对象来唯一标识这个结点
11                 this->m_root = node;
12             }
13             else
14             {
15                 GTreeNode<T>* np = find(node->parent);  // 插入结点的父结点是不是在树中
16                 if( np != NULL )
17                 {
18                     GTreeNode<T>* n = dynamic_cast<GTreeNode<T>*>(node);
19 
20                     if( np->child.find(n) < 0 )  // 当前要插入的父结点没有需要插入的子结点,返回值小于 0
21                     {
22                         np->child.insert(n);  // 插入到父结点的子结点链表里面去
23                     }
24                 }
25                 else
26                 {
27                     THROW_EXCEPTION(InvalidOperationException, "Invalid parent tree node ...");
28                 }
29             }
30         }
31         else
32         {
33             THROW_EXCEPTION(InvalidParameterException, "Parameter node cannot be NULL ...");
34         }
35         return ret;
36    }

             

5,数据元素插入:

 

       1,只用维护插入结点的 parent 和 value 以及父结点的 parent 就可以了,至于自己的 child 链表,还是个空链表,不用管,而父结点的 child 是要维护的,用新结点插入方法维护;

  2,代码实现:

 1    bool insert(const T& value, TreeNode<T>* parent)
 2     {
 3         bool ret = true;
 4         GTreeNode<T>* node = GTreeNode<T>::NewNode();  // 使用工厂方法
 5 
 6         if( node != NULL )
 7         {
 8             node->value = value;
 9             node->parent = parent;
10 
11             insert(node);  // 本文 4.4 中 insert 函数复用
12         }
13         else
14         {
15             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create new tree node ...");
16         }
17 
18         return ret;
19    }

         

6,插入新结点的操作中,新结点的 child 都不用管;

7,小结:

       1,插入操作是构建树的唯一操作;

       2,执行插入操作时必须指明结点间的父子关系;

       3,插入操作必须正确处理指向父结点的指针;

       4,插入数据元素时需要从堆空间中创建结点;

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