二叉树中的结点删除,清除,属性操作

上节实现了二叉树中的结点查找、插入,这节实现二叉树中的结点删除,清除,属性操作


目录

1、二叉树中的结点删除

2、二叉树中的结点清除

3、二叉树中属性操作函数的实现

1、二叉树中结点的数目

2、二叉树的高度 

3、二叉树的度数 

4、编程实验


1、二叉树中的结点删除

删除的方式 (与通用树结构一致)

    -基于数据元素值的删除 

                    SharedPointer< Tree<T> > remove(const T& value

    -基于结点的删除 

                    SharedPointer< Tree<T> > remove(TreeNode<T>* node

二叉树中结点的删除

       

                                                           使用智能指针管理子树

删除操作功能的定义 

    void remove(BTreeNode<T>* node, BTree<T>*&  ret

            ● 将node为根结点的子树从原来的二叉树中删除 

            ● ret作为子树返回( ret指向堆空间中的二叉树对象 )

删除功能函数的实现

                                

编程实验 

二叉树结点的删除操作

BTree.h

#ifndef BTREE_H
#define BTREE_H

#include "Tree.h"
#include "BTreeNode.h"
#include "Exception.h"
#include "LinkQueue.h"
#include "DynamicArray.h"

namespace DTLib
{

template < typename T >
class BTree : public Tree<T>
{
protected:
    // ...

    virtual void remove(BTreeNode<T>* node, BTree<T>*& ret)
    {
        ret = new BTree<T>(); 

        if(ret == NULL)
        {
            THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create new tree ...");
        }
        else
        {
            if(root() == node) 
            {
                this->m_root = NULL;
            }
            else    // 断绝父子关系
            {
                BTreeNode<T>* parent = dynamic_cast<BTreeNode<T>*>(node->parent);

                if(parent->left == node)
                {
                    parent->left = NULL;
                }
                else if(parent->right == node)
                {
                    parent->right = NULL;
                }

                node->parent = NULL;
            }
        }

        ret->m_root = node;
    }

public:
    // ...

    SharedPointer< Tree<T> > remove(const T& value)
    {
        BTree<T>* ret = NULL;

        BTreeNode<T>* node = find(value);

        if(node == NULL)
        {
            THROW_EXCEPTION(InvalidParameterException, "Can not find the tree node via value ...");
        }
        else
        {
            remove(node, ret);
            m_queue.clear();
        }

        return ret;
    }

    SharedPointer< Tree<T> > remove(TreeNode<T>* node)
    {
        BTree<T>* ret = NULL;

        node = find(node);

        if(node == NULL)
        {
            THROW_EXCEPTION(InvalidParameterException, "Parameter node is invalid ...");
        }
        else
        {
            remove(dynamic_cast<BTreeNode<T>*>(node), ret);
            m_queue.clear();
        }

        return ret;
    }

    // ...
};
}
#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};

    SharedPointer< Tree<int> > sp = bt.remove(3); 

    for(int i=0; i<5; i++)
    {
        TreeNode<int>* node = sp->find(a[i]);

        while(node)
        {
            cout << node->value << " ";
            node = node->parent;
        }

        cout << endl;

    }

    return 0;
}

 

 

2、二叉树中的结点清除

清除操作的定义

    void clear() 

          ● 将二叉树中的所有结点清除释放堆中的结点

二叉树中结点的清除 

            

                                                      递归的操作(先清除左子树再右子树再根结点)

 清除操作功能的定义 

    freenode 

          ● 清除 node 为根结点的二叉树 

          ● 释放二叉树中的每一个结点 

            

编程实验 

清除二叉树中的结点

#ifndef BTREE_H
#define BTREE_H

#include "Tree.h"
#include "BTreeNode.h"
#include "Exception.h"
#include "LinkQueue.h"
#include "DynamicArray.h"

namespace DTLib
{

template < typename T >
class BTree : public Tree<T>
{
protected:
    // ...

    virtual void free(BTreeNode<T>* node)
    {
        if(node != NULL)
        {
            free(node->left);
            free(node->right);

            if( node->flag() )
            {
                delete node; // 堆空间的结点才delete
            }
        }
    }

public:
    // ...

    void clear()
    {
        free(root());

        this->m_root = NULL;
    }


    ~BTree()
    {
        clear();
    }
};
}
#endif // BTREE_H

小结 

            删除操作将目标结点所代表的子树移除 

            删除操作必须完善处理父结点和子结点的关系 

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

            销毁结点时判断是否释放对应的内存空间(工厂模式) 

 

3、二叉树中属性操作函数的实现

                          count() = 10; height() = 4; degree() = 2; 

1、二叉树中结点的数目

定义功能: count( node ) 

       功能: 在node为根结点的二叉树中统计结点数目 

        

                                              左子树结点数 + 右子树结点数 + 1

2、二叉树的高度 

定义功能: height( node ) 

       功能: 获取node为根结点的二叉树的高度 

        

                                             取左子树高度与右子树高度最大值 + 1

3、二叉树的度数 

定义功能: degree( node ) 

       功能: 获取 node 为根结点的二叉树的度数 

            

                          !!node->left + !!node->right:当前根结点的度  (两次取反相当于强制bool)

4、编程实验

#ifndef BTREE_H
#define BTREE_H

#include "Tree.h"
#include "BTreeNode.h"
#include "Exception.h"
#include "LinkQueue.h"
#include "DynamicArray.h"

namespace DTLib
{

template < typename T >
class BTree : public Tree<T>
{
protected:
    // ...

    int count(BTreeNode<T>* node) const
    {
//        int ret = 0; 
                
//        if(node != NULL) 
//        { 
//            ret = count(node->left) + count(node->right) + 1; 
//        } 
                
//        return ret; 
        
        return (node != NULL) ? (count(node->left) + count(node->right) + 1) : 0;
    }

    int height(BTreeNode<T>* node) const
    {
        int ret = 0;

        if(node != NULL)
        {
            int lh = height(node->left);
            int rh = height(node->right);

            ret = (lh > rh ? lh: rh) + 1;
        }

        return ret;
    }

    int degree(BTreeNode<T>* node) const
    {
        int ret = 0;

        if(node != NULL)
        {
            /*
                    写法1:不高效的写法(二叉树结点的度最大为2)
                    int dl = degree(node->left); 
                    int dr = degree(node->right); 
                    
                    ret = (!!node->left + !!node->right);   // 根结点度  0, 1, 2 
                    
                    if(ret < dl) 
                    { 
                        ret = dl; 
                    } 
                    
                    if(ret < dr) 
                    { 
                        ret = dr; 
                    } 
            */      
            
            /*      
                    写法2:代码冗余
                    ret = (!!node->left + !!node->right); // 可以先得到结点的度
                    
                    if(ret < 2) 
                    { 
                        int dl = degree(node->left); 
                        
                        if(ret < dl) 
                        { 
                            ret = dl; 
                        } 
                    } 
                    
                    if(ret < 2) 
                    { 
                        int dr = degree(node->right); 
                        
                        if(ret < dr) 
                        { 
                            ret = dr; 
                        } 
                    } 
                    
            */ 

            // 写法2的升级
            BTreeNode<T>* child[] = {node->left, node->right};

            ret = (!!node->left + !!node->right);

            for(int i=0; (i<2) && (ret<2); i++)
            {
                int d = degree(child[i]);

                if(ret < d)
                {
                    ret = d;
                }
            }

        }

        return ret;
    }

public:
    // ...

    int degree() const
    {
        return degree(root());
    }
    int count() const
    {
        return count(root());
    }
    int height() const
    {
        return height(root());
    }
    
     // ...
  
};
}
#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);

    cout << bt.count() << endl;
    cout << bt.height() << endl;
    cout << bt.degree() << endl;


    return 0;
}

                            

 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值