第63课 - 二叉树中的结点插入操作

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 (二叉树结构)的结点 

                删除操作和清除操作




猜你喜欢

转载自blog.csdn.net/qq_39654127/article/details/80499573