1、二叉树中的结点插入操作
需要考虑的问题
是否能够在二叉树的任意结点处插入子结点?
是否需要指定新数据元素(新结点)的插入位置?
二叉树结点的位置枚举类型
插入的方式
-插入新结点
bool insert(TreeNode<T>* node)
bool insert(TreeNode<T>* node, BTNodePos pos)
-插入数据元素
bool insert(const T& value, TreeNode<T>* parent)
bool insert( const T& value, TreeNode< T>* parent, BTNodePos pos) 新结点的插入
5的左子树位置不能插入,2都不能插入
指定位置的结点插入
插入新结点
插入数据元素
2、编程实验
二叉树的插入操作 insert
BTreeNode.h 增加枚举常量
#ifndef BTREENODE_H #define BTREENODE_H #include "TreeNode.h" namespace DTLib { enum BTNodePos { ANY, LEFT, RIGHT }; template < typename T > class BTreeNode : public TreeNode<T> { public: BTreeNode<T>* left; BTreeNode<T>* right; BTreeNode() { left = NULL; right = NULL; } static BTreeNode<T>* NewNode() { BTreeNode<T>* ret = new BTreeNode<T>(); if(ret) { ret->m_flag = true; } return ret; } }; } #endif // BTREENODE_H
BTree.h
#ifndef BTREE_H #define BTREE_H #include "Tree.h" #include "BTreeNode.h" #include "Exception.h" #include "LinkQueue.h" namespace DTLib { template < typename T > class BTree : public Tree<T> { protected: virtual BTreeNode<T>* find(BTreeNode<T>* node,const T& value) const { BTreeNode<T>* ret = NULL; if(node != NULL) { if(node->value == value) { ret = node; } else { if(ret == NULL) { ret = find(node->left,value); } if(ret == NULL) //左子树没找到,找右子树 { ret = find(node->right,value); } } } return ret; } virtual BTreeNode<T>* find(BTreeNode<T>* node,BTreeNode<T>* obj) const { BTreeNode<T>* ret = NULL; if(node == obj) { ret = node; } else { if(node != NULL) { if(ret == NULL) { ret = find(node->left,obj); } if(ret == NULL) { ret = find(node->right,obj); } } } return ret; } virtual bool insert(BTreeNode<T>* n,BTreeNode<T>* np,BTNodePos pos) { bool ret = true; if( pos == ANY ) { if(np->left == NULL) { np->left = n; } else if(np->right == NULL) { np->right = n; } else { ret = false; } } else if( pos == LEFT ) { if(np->left == NULL) { np->left = n; } else { ret = false; } } else if( pos == RIGHT ) { if(np->right == NULL) { np->left = n; } else { ret = false; } } else { ret = false; } return ret; } public: bool insert(TreeNode<T>* node) { return insert(node,ANY); } virtual bool insert(TreeNode<T>* node,BTNodePos pos) { bool ret = true; if(node != NULL) { if(this->m_root == NULL) { node->parent = NULL; this->m_root = node; } else { BTreeNode<T>* np = find(node->parent); if(np != NULL) { ret = insert(dynamic_cast<BTreeNode<T>*>(node),np,pos); } else { THROW_EXCEPTION(InvalidParameterException,"Invalid parent tree node ..."); } } } else { THROW_EXCEPTION(InvalidParameterException,"Parameter node can not be NULL ..."); } return ret; } bool insert(const T& value,TreeNode<T>* parent) { return insert(value,parent,ANY); } virtual bool insert(const T& value,TreeNode<T>* parent,BTNodePos pos) { bool ret = true; BTreeNode<T>* node = BTreeNode<T>::NewNode(); if(node == NULL) { THROW_EXCEPTION(NoEnoughMemoryException,"No memory to create new node ..."); } else { node->value = value; node->parent = parent; ret = insert(node,pos); if(!ret) { delete node; } } return ret; } SharedPointer< Tree<T> > remove(const T& value) { return NULL; } SharedPointer< Tree<T> > remove(TreeNode<T>* node) { return NULL; } BTreeNode<T>* find(const T& value) const { return find(root(),value); } BTreeNode<T>* find(TreeNode<T>* node) const { return find(root(),dynamic_cast<BTreeNode<T>*>(node)); } BTreeNode<T>* root() const { return dynamic_cast<BTreeNode<T>*>(this->m_root); } int degree() const { return 0; } int count() const { return 0; } int height() const { return 0; } void clear() { this->m_root = NULL; } ~BTree() { clear(); } }; } #endif // BTREE_H
main.cpp
#include <iostream> #include"BTree.h" using namespace std; using namespace DTLib; int main() { BTree<int> bt; BTreeNode<int>* n = NULL; bt.insert(1,NULL); n = bt.find(1); bt.insert(2,n); bt.insert(3,n); n = bt.find(2); bt.insert(4,n); bt.insert(5,n); n = bt.find(4); bt.insert(8,n); bt.insert(9,n); n = bt.find(5); bt.insert(10,n); n = bt.find(3); bt.insert(6,n); bt.insert(7,n); n = bt.find(6); bt.insert(11,n,LEFT); int a[] = {8,9,10,11,7}; for(int i=0;i<5;i++) { TreeNode<int>* node = bt.find(a[i]); while(node) { cout<<node->value<<" "; node = node->parent; } cout<<endl; } return 0; }
3、小结
二叉树的插入操作需要指明插入的位置
插入操作必须正确处理指向父结点的指针
插入数据元素时需要从堆空间中创建结点
当数据元素插入 失败时需要释放结点空间4、实战预告
To be continued…
思考:
如何实现BTree (二叉树结构)的结点
删除操作和清除操作?