1,需要考虑的问题:
1,是否能够在二叉树任意结点处插入子结点?
1,不能,二叉树每个结点的成员是相对固定的,只有两个指向左右后继结点的指针成员;
2,是否需要指定新数据元素(新结点)的插入位置?
1,需要;
2,插入新结点(或数据元素)作为叶结点孩子,具体插入左边还是右边呢?
2,二叉树结点的位置枚举类型:
1,enum BTNodePos
{
ANY, // 不介意,左右孩子都可以
LEFT, // 插入新结点只能作为左孩子;
RIGHT // 插入新结点只能作为右孩子;
};
3,插入方式:
1,插入新结点:
1,bool insert(TreeNode<T>* node);
1,只要新结点能插入就可以,不管左边还是右边的位置;
2,左右没有位置,返回 false;
2,bool insert(TreeNode<T>* node, BTNodePos pos);
1,按照 pos 要求插入位置,要求位置没有位置,则返回 false;
2,通用树结构插入操作只会返回 true;
2,插入数据元素:
1,bool insert(const T& value, TreeNode<T>* parent);
1,只要有位置就插入;
2,bool insert(const T& value, TreeNode<T>* parent, BTNodePos pos);
1,按 pos 要求插入;
4,新结点的插入:
1,查找;
2,插入;
5,指定位置的结点插入:
6,插入新结点:
7,插入数据元素:
8,二叉树的插入成员函数实现:
1,基于结点的插入
1 bool insert(TreeNode<T>* node) 2 { 3 return insert(node, ANY); //将 node 作为目标结点插入,插入位置没有要求 4 } 5 6 virtual bool insert(TreeNode<T>* node, BTNodePos pos) 7 { 8 bool ret = true; 9 10 if( node != NULL ) // 要插入的结点非空 11 { 12 if( this->m_root == NULL ) // 要插入的对象树是空树 13 { 14 node->parent = NULL; 15 this->m_root = node; 16 } 17 else // 非空树 18 { 19 BTreeNode<T>* np = find(node->parent); // 目标父结点在当前树中 20 if( np != NULL ) // 在参数中 21 { 22 insert(dynamic_cast<BTreeNode<T>*>(node), np, pos); 23 } 24 else 25 { 26 THROW_EXCEPTION(InvalidParameterException, "Invalid parent tree node ..."); 27 } 28 } 29 } 30 else 31 { 32 THROW_EXCEPTION(InvalidParameterException, "Parameter node can not be NULL"); 33 } 34 return ret; 35 }
2,基于数据值的插入:
1 bool insert(const T& value, TreeNode<T>* parent) 2 { 3 return insert(value, parent, ANY); // 位置没有要求 4 } 5 virtual bool insert(const T& value, TreeNode<T>* parent, BTNodePos pos) 6 { 7 bool ret = true; 8 9 BTreeNode<T>* node = BTreeNode<T>::NewNode(); 10 11 if( node == NULL ) // 申请未成功 12 { 13 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create new node ..."); 14 } 15 else 16 { 17 node->value = value; // 插入之前设置成员的值 18 node->parent = parent; // 目标父结点设置好 19 20 ret = insert(node, pos); 21 22 if( !ret ) // 若果插入不成功;就释放这个结点; 23 { 24 delete node; 25 } 26 } 27 return ret; 28 }
9,小结:
1,二叉树的插入操作需要指明插入的位置;
1,定义枚举常量;
2,插入操作必须正确处理指向父结点的指针;
3,插入数据元素时需要从堆空间中创建结点;
4,当数据元素插入失败时需要释放结点空间;