二叉树中的结点删除
删除方式
基于数据元素值的删除
- SharedPointer<Tree<T>> remove(const T &value);
基于结点的删除
- SharedPointer<Tree<T>> remove(TreeNode<T> *node);
二叉树中结点的删除
删除操作功能的定义
void removeP(BTreeNode<T> node, Btree<T> *&ret);
- 将 node 作为根结点的子树从原来的二叉树中删除
- ret 作为子树返回 (ret 指向堆空间中的二叉树对象)
编程实验:二叉树结点的删除操作
#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>
{
public:
BTree() = default;
bool insert(TreeNode<T> *node) override
{
return insert(node, ANY);
}
virtual bool insert(TreeNode<T> *node, BTNodePos pos)
{
bool ret = true;
if (node != nullptr)
{
if (this->m_root == nullptr)
{
node->parent = nullptr;
this->m_root = node;
}
else
{
BTreeNode<T> *np = find(node->parent);
if (np != nullptr)
{
ret = insert(dynamic_cast<BTreeNode<T>*>(node), np, pos);
}
else
{
THROW_EXCEPTION(InvalidParameterExcetion, "Invalid parent tree node ...");
}
}
}
else
{
THROW_EXCEPTION(InvalidParameterExcetion, "Parameter can not be null ...");
}
return ret;
}
bool insert(const T &value, TreeNode<T> *parent) override
{
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 != nullptr)
{
node->value = value;
node->parent = parent;
ret = insert(node, pos);
if (!ret)
{
delete node;
}
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory to create node ...");
}
return ret;
}
SharedPointer<Tree<T>> remove(const T &value) override
{
BTree<T> *ret = nullptr;
BTreeNode<T> *node = find(value);
if (node != nullptr)
{
remove(node, ret);
}
else
{
THROW_EXCEPTION(InvalidParameterExcetion, "Can not find the tree node via value ...");
}
return ret;
}
SharedPointer<Tree<T>> remove(TreeNode<T> *node) override
{
BTree<T> *ret = nullptr;
node = find(node);
if (node != nullptr)
{
remove(dynamic_cast<BTreeNode<T>*>(node), ret);
}
else
{
THROW_EXCEPTION(InvalidParameterExcetion, "Parameter node is invalid ...");
}
return ret;
}
BTreeNode<T>* find(const T &value) const override
{
return find(root(), value);
}
BTreeNode<T>* find(TreeNode<T> *node) const override
{
return find(root(), dynamic_cast<BTreeNode<T>*>(node));
}
BTreeNode<T>* root() const override
{
return dynamic_cast<BTreeNode<T>*>(this->m_root);
}
int degree() const override
{
return 0;
}
int count() const override
{
return 0;
}
int height() const
{
return 0;
}
void clear() override
{
this->m_root = nullptr;
}
~BTree()
{
clear();
}
protected:
BTree(const BTree<T>&) = default;
BTree<T>& operator = (const BTree<T>&) = default;
virtual BTreeNode<T>* find(BTreeNode<T> *node, const T &value) const
{
BTreeNode<T> *ret = nullptr;
if (node != nullptr)
{
if (node->value == value)
{
ret = node;
}
else
{
if (ret == nullptr)
{
ret = find(node->left, value);
}
if (ret == nullptr)
{
ret = find(node->right, value);
}
}
}
return ret;
}
virtual BTreeNode<T>* find(BTreeNode<T> *node, BTreeNode<T> *obj) const
{
BTreeNode<T> *ret = nullptr;
if (node == obj)
{
ret = node;
}
else
{
if (node != nullptr)
{
if (ret == nullptr)
{
ret = find(node->left, obj);
}
if (ret == nullptr)
{
ret = find(node->right, obj);
}
}
}
return ret;
}
virtual bool insert(BTreeNode<T> *node, BTreeNode<T> *np, BTNodePos pos)
{
bool ret = true;
if (pos == ANY)
{
if (np->left == nullptr)
{
np->left = node;
}
else if (np->right == nullptr)
{
np->right = node;
}
else
{
ret = false;
}
}
else if (pos == LEFT)
{
if (np->left == nullptr)
{
np->left = node;
}
else
{
ret = false;
}
}
else if (pos == RIGHT)
{
if (np->right == nullptr)
{
np->right = node;
}
else
{
ret = false;
}
}
return ret;
}
virtual void remove(BTreeNode<T> *node, BTree<T> *&ret)
{
ret = new BTree<T>();
if (ret != nullptr)
{
if (root() == node)
{
this->m_root = nullptr;
}
else
{
BTreeNode<T> *parent = dynamic_cast<BTreeNode<T>*>(node->parent);
if (node == parent->left)
{
parent->left = nullptr;
}
else if (node == parent->right)
{
parent->right = nullptr;
}
node->parent = nullptr;
}
ret->m_root = node;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create btree ...");
}
}
};
}
#endif // BTREE_H
文件:main.cpp
#include <iostream>
#include "BTreeNode.h"
#include "BTree.h"
using namespace std;
using namespace DTLib;
int main()
{
BTree<int> bt;
BTreeNode<int> *n = nullptr;
bt.insert(1, nullptr);
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);
SharedPointer<Tree<int>> sp = bt.remove(3);
int a[] = {8, 9, 10, 6, 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;
}
cout << "----------" << endl;
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;
}
输出:
8 4 2 1
9 4 2 1
10 5 2 1
----------
6 3
7 3
二叉树的清除
清除操作的定义
void clear();
- 将二叉树中的所有结点清除 (释放堆中的结点)
二叉树中结点的清除
清除操作的功能定义
free(node)
- 清除 node 为根节点的二叉树
- 释放二叉树中的每一个结点
编程实验:清除二叉树中的结点
文件: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>
{
public:
BTree() = default;
bool insert(TreeNode<T> *node) override
{
return insert(node, ANY);
}
virtual bool insert(TreeNode<T> *node, BTNodePos pos)
{
bool ret = true;
if (node != nullptr)
{
if (this->m_root == nullptr)
{
node->parent = nullptr;
this->m_root = node;
}
else
{
BTreeNode<T> *np = find(node->parent);
if (np != nullptr)
{
ret = insert(dynamic_cast<BTreeNode<T>*>(node), np, pos);
}
else
{
THROW_EXCEPTION(InvalidParameterExcetion, "Invalid parent tree node ...");
}
}
}
else
{
THROW_EXCEPTION(InvalidParameterExcetion, "Parameter can not be null ...");
}
return ret;
}
bool insert(const T &value, TreeNode<T> *parent) override
{
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 != nullptr)
{
node->value = value;
node->parent = parent;
ret = insert(node, pos);
if (!ret)
{
delete node;
}
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No enough memory to create node ...");
}
return ret;
}
SharedPointer<Tree<T>> remove(const T &value) override
{
BTree<T> *ret = nullptr;
BTreeNode<T> *node = find(value);
if (node != nullptr)
{
remove(node, ret);
}
else
{
THROW_EXCEPTION(InvalidParameterExcetion, "Can not find the tree node via value ...");
}
return ret;
}
SharedPointer<Tree<T>> remove(TreeNode<T> *node) override
{
BTree<T> *ret = nullptr;
node = find(node);
if (node != nullptr)
{
remove(dynamic_cast<BTreeNode<T>*>(node), ret);
}
else
{
THROW_EXCEPTION(InvalidParameterExcetion, "Parameter node is invalid ...");
}
return ret;
}
BTreeNode<T>* find(const T &value) const override
{
return find(root(), value);
}
BTreeNode<T>* find(TreeNode<T> *node) const override
{
return find(root(), dynamic_cast<BTreeNode<T>*>(node));
}
BTreeNode<T>* root() const override
{
return dynamic_cast<BTreeNode<T>*>(this->m_root);
}
int degree() const override
{
return 0;
}
int count() const override
{
return 0;
}
int height() const
{
return 0;
}
void clear() override
{
free(root());
this->m_root = nullptr;
}
~BTree()
{
clear();
}
protected:
BTree(const BTree<T>&) = default;
BTree<T>& operator = (const BTree<T>&) = default;
virtual BTreeNode<T>* find(BTreeNode<T> *node, const T &value) const
{
BTreeNode<T> *ret = nullptr;
if (node != nullptr)
{
if (node->value == value)
{
ret = node;
}
else
{
if (ret == nullptr)
{
ret = find(node->left, value);
}
if (ret == nullptr)
{
ret = find(node->right, value);
}
}
}
return ret;
}
virtual BTreeNode<T>* find(BTreeNode<T> *node, BTreeNode<T> *obj) const
{
BTreeNode<T> *ret = nullptr;
if (node == obj)
{
ret = node;
}
else
{
if (node != nullptr)
{
if (ret == nullptr)
{
ret = find(node->left, obj);
}
if (ret == nullptr)
{
ret = find(node->right, obj);
}
}
}
return ret;
}
virtual bool insert(BTreeNode<T> *node, BTreeNode<T> *np, BTNodePos pos)
{
bool ret = true;
if (pos == ANY)
{
if (np->left == nullptr)
{
np->left = node;
}
else if (np->right == nullptr)
{
np->right = node;
}
else
{
ret = false;
}
}
else if (pos == LEFT)
{
if (np->left == nullptr)
{
np->left = node;
}
else
{
ret = false;
}
}
else if (pos == RIGHT)
{
if (np->right == nullptr)
{
np->right = node;
}
else
{
ret = false;
}
}
return ret;
}
virtual void remove(BTreeNode<T> *node, BTree<T> *&ret)
{
ret = new BTree<T>();
if (ret != nullptr)
{
if (root() == node)
{
this->m_root = nullptr;
}
else
{
BTreeNode<T> *parent = dynamic_cast<BTreeNode<T>*>(node->parent);
if (node == parent->left)
{
parent->left = nullptr;
}
else if (node == parent->right)
{
parent->right = nullptr;
}
node->parent = nullptr;
}
ret->m_root = node;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create btree ...");
}
}
virtual void free(BTreeNode<T> *node)
{
if (node != nullptr)
{
free(node->left);
free(node->right);
if (node->flag())
{
delete node;
}
}
}
};
}
#endif // BTREE_H
文件:main.cpp
#include <iostream>
#include "BTreeNode.h"
#include "BTree.h"
using namespace std;
using namespace DTLib;
int main()
{
BTree<int> bt;
BTreeNode<int> *n = nullptr;
bt.insert(1, nullptr);
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);
bt.clear();
int a[] = {8, 9, 10, 6, 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;
}
输出:
小结
- 删除操作将目标结点所代表的子树移除
- 删除操作必须完善处理父结点和子结点的关系
- 清除操作用于销毁树中的每个结点
- 销毁结点时判断是否释放对应的内存空间(工厂模式)
以上内容整理于狄泰软件学院系列课程,请大家保护原创!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。