树中结点的删除操作:
- 删除的方式:
— 基于数据元素值的删除:SharedPointer< Tree<T> > remove(const T& value)
— 基于结点的删除:SharedPointer< Tree<T> > remove(TreeNode<T>* node)
删除操作成员函数的设计要点:
1、将被删结点所代表的子树进行删除
2、删除函数返回一颗堆空间的树
3、具体返回值为指向树的智能指针对象
实用的设计原则:当需要从函数中返回堆中的对象时,使用智能指针(SharedPointer)作为函数的返回值。
删除操作功能的定义:void remove(GTreeNode<T>* node, GTree<T>*& ret)
— 将 node 为根结点的子树从原来的树中删除
— ret 作为子树返回(ret 指向堆空间中的树对象)、
void remove(GTreeNode<T>* node, GTree<T>*& ret)
{
ret = new GTree<T>;
if(ret != nullptr)
{
if(root() == node)
{
this->m_root == nullptr;
}
else
{
LinkList<GTreeNode<T>*>& child = dynamic_cast<GTreeNode<T>*>(node->parent)->child;
child.remove(child.find(node));
node->parent = nullptr;
}
ret->m_root = node;
}
else
{
THROW_EXCEPTION(NoEnoughMemoryException, "no enough memory to create tree");
}
}
SharedPointer< Tree<T> > remove(const T& value)
{
GTree<T>* ret = nullptr;
GTreeNode<T>* node = find(value);
if(node != nullptr)
{
remove(node, ret);
}
else
{
THROW_EXCEPTION(InvalidParameterException, "can not find node");
}
return ret;
}
SharedPointer< Tree<T> > remove(TreeNode<T>* node)
{
GTree<T>* ret = nullptr;
node = find(node);
if(node != nullptr)
{
remove(dynamic_cast<GTreeNode<T>*>(node) , ret);
}
else
{
THROW_EXCEPTION(InvalidParameterException, "parameter node is invalid");
}
return ret;
}
main.cpp
#include <iostream>
#include "GTree.h"
using namespace std;
using namespace XiebsLib;
int main()
{
GTree<char> t;
GTreeNode<char>* node = nullptr;
t.insert('A', nullptr);
node = t.find('A');
t.insert('B', node);
t.insert('C', node);
t.insert('D', node);
node = t.find('B');
t.insert('E', node);
t.insert('F', node);
node = t.find('E');
t.insert('K', node);
t.insert('L', node);
node = t.find('C');
t.insert('G', node);
node = t.find('G');
t.insert('N', node);
node = t.find('D');
t.insert('H', node);
t.insert('I', node);
t.insert('J', node);
node = t.find('H');
t.insert('M', node);
// t.clear();
t.remove('D');
const char* s = "KLFNMIJ";
for(int i = 0; i < 7; i++)
{
TreeNode<char>* node = t.find(s[i]);
while( node != nullptr )
{
cout << node->value << " ";
node = node->parent;
}
cout << endl;
}
return 0;
}
- 小结
1、删除操作将目标结点所代表的子树移除
2、删除操作必须完善处理父结点和子结点的关系
3、删除操作的返回值为指向树的智能指针对象
4、函数中返回堆中的对象时,使用智能指针作为返回值