二叉树删除结点 c语言,【数据结构】64_二叉树中的结点删除与清除

二叉树中的结点删除

删除方式

基于数据元素值的删除

SharedPointer> remove(const T &value);

基于结点的删除

SharedPointer> remove(TreeNode *node);

二叉树中结点的删除

bVbDkfv

删除操作功能的定义

void removeP(BTreeNode node, Btree *&ret);

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

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

bVbDkfD

编程实验:二叉树结点的删除操作

#ifndef BTREE_H

#define BTREE_H

#include "Tree.h"

#include "BTreeNode.h"

#include "Exception.h"

#include "LinkQueue.h"

namespace DTLib

{

template

class BTree : public Tree

{

public:

BTree() = default;

bool insert(TreeNode *node) override

{

return insert(node, ANY);

}

virtual bool insert(TreeNode *node, BTNodePos pos)

{

bool ret = true;

if (node != nullptr)

{

if (this->m_root == nullptr)

{

node->parent = nullptr;

this->m_root = node;

}

else

{

BTreeNode *np = find(node->parent);

if (np != nullptr)

{

ret = insert(dynamic_cast*>(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 *parent) override

{

return insert(value, parent, ANY);

}

virtual bool insert(const T &value, TreeNode *parent, BTNodePos pos)

{

bool ret = true;

BTreeNode *node = BTreeNode::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> remove(const T &value) override

{

BTree *ret = nullptr;

BTreeNode *node = find(value);

if (node != nullptr)

{

remove(node, ret);

}

else

{

THROW_EXCEPTION(InvalidParameterExcetion, "Can not find the tree node via value ...");

}

return ret;

}

SharedPointer> remove(TreeNode *node) override

{

BTree *ret = nullptr;

node = find(node);

if (node != nullptr)

{

remove(dynamic_cast*>(node), ret);

}

else

{

THROW_EXCEPTION(InvalidParameterExcetion, "Parameter node is invalid ...");

}

return ret;

}

BTreeNode* find(const T &value) const override

{

return find(root(), value);

}

BTreeNode* find(TreeNode *node) const override

{

return find(root(), dynamic_cast*>(node));

}

BTreeNode* root() const override

{

return dynamic_cast*>(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&) = default;

BTree& operator = (const BTree&) = default;

virtual BTreeNode* find(BTreeNode *node, const T &value) const

{

BTreeNode *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* find(BTreeNode *node, BTreeNode *obj) const

{

BTreeNode *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 *node, BTreeNode *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 *node, BTree *&ret)

{

ret = new BTree();

if (ret != nullptr)

{

if (root() == node)

{

this->m_root = nullptr;

}

else

{

BTreeNode *parent = dynamic_cast*>(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

#include "BTreeNode.h"

#include "BTree.h"

using namespace std;

using namespace DTLib;

int main()

{

BTree bt;

BTreeNode *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> sp = bt.remove(3);

int a[] = {8, 9, 10, 6, 7};

for (int i=0; i<5; ++i)

{

TreeNode *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 *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();

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

二叉树中结点的清除

bVbDkil

清除操作的功能定义

free(node)

清除 node 为根节点的二叉树

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

bVbDkir

编程实验:清除二叉树中的结点

文件:BTree.h

#ifndef BTREE_H

#define BTREE_H

#include "Tree.h"

#include "BTreeNode.h"

#include "Exception.h"

#include "LinkQueue.h"

namespace DTLib

{

template

class BTree : public Tree

{

public:

BTree() = default;

bool insert(TreeNode *node) override

{

return insert(node, ANY);

}

virtual bool insert(TreeNode *node, BTNodePos pos)

{

bool ret = true;

if (node != nullptr)

{

if (this->m_root == nullptr)

{

node->parent = nullptr;

this->m_root = node;

}

else

{

BTreeNode *np = find(node->parent);

if (np != nullptr)

{

ret = insert(dynamic_cast*>(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 *parent) override

{

return insert(value, parent, ANY);

}

virtual bool insert(const T &value, TreeNode *parent, BTNodePos pos)

{

bool ret = true;

BTreeNode *node = BTreeNode::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> remove(const T &value) override

{

BTree *ret = nullptr;

BTreeNode *node = find(value);

if (node != nullptr)

{

remove(node, ret);

}

else

{

THROW_EXCEPTION(InvalidParameterExcetion, "Can not find the tree node via value ...");

}

return ret;

}

SharedPointer> remove(TreeNode *node) override

{

BTree *ret = nullptr;

node = find(node);

if (node != nullptr)

{

remove(dynamic_cast*>(node), ret);

}

else

{

THROW_EXCEPTION(InvalidParameterExcetion, "Parameter node is invalid ...");

}

return ret;

}

BTreeNode* find(const T &value) const override

{

return find(root(), value);

}

BTreeNode* find(TreeNode *node) const override

{

return find(root(), dynamic_cast*>(node));

}

BTreeNode* root() const override

{

return dynamic_cast*>(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&) = default;

BTree& operator = (const BTree&) = default;

virtual BTreeNode* find(BTreeNode *node, const T &value) const

{

BTreeNode *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* find(BTreeNode *node, BTreeNode *obj) const

{

BTreeNode *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 *node, BTreeNode *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 *node, BTree *&ret)

{

ret = new BTree();

if (ret != nullptr)

{

if (root() == node)

{

this->m_root = nullptr;

}

else

{

BTreeNode *parent = dynamic_cast*>(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 *node)

{

if (node != nullptr)

{

free(node->left);

free(node->right);

if (node->flag())

{

delete node;

}

}

}

};

}

#endif // BTREE_H

文件:main.cpp

#include

#include "BTreeNode.h"

#include "BTree.h"

using namespace std;

using namespace DTLib;

int main()

{

BTree bt;

BTreeNode *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 *node = bt.find(a[i]);

while (node)

{

cout << node->value << " ";

node = node->parent;

}

cout << endl;

}

return 0;

}

输出:

小结

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

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

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

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

以上内容整理于狄泰软件学院系列课程,请大家保护原创!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值