11_排序二叉树删除-3
2015-12-12 11:44
465 查看
出处: http://blog.csdn.net/feixiaoxing/article/details/6868221
3 普通节点的删除
3.1 删除的节点没有左子树,也没有右子树
测试用例1: 删除节点6
[cpp] view
plaincopy
/*
*
* 10 ======> 10
* / \ \
* 6 15 15
*
*/
static void test8()
{
TREE_NODE* pTreeNode = NULL;
assert(TRUE == insert_node_into_tree(&pTreeNode, 10));
assert(TRUE == insert_node_into_tree(&pTreeNode, 6));
assert(6 == pTreeNode->left_child->data);
assert(TRUE == insert_node_into_tree(&pTreeNode, 15));
assert(TRUE == delete_node_from_tree(&pTreeNode, 6));
assert(NULL == pTreeNode->left_child);
free(pTreeNode->right_child);
free(pTreeNode);
}
测试用例2: 删除节点15
[cpp] view
plaincopy
/*
*
* 10 ======> 10
* / \ /
* 6 15 6
*
*/
static void test9()
{
TREE_NODE* pTreeNode = NULL;
assert(TRUE == insert_node_into_tree(&pTreeNode, 10));
assert(TRUE == insert_node_into_tree(&pTreeNode, 6));
assert(TRUE == insert_node_into_tree(&pTreeNode, 15));
assert(15 == pTreeNode->right_child->data);
assert(TRUE == delete_node_from_tree(&pTreeNode, 15));
assert(NULL == pTreeNode->right_child);
free(pTreeNode->right_child);
free(pTreeNode);
}
那么代码应该怎么编写呢?
[cpp] view
plaincopy
STATUS _delete_node_from_tree(TREE_NODE* pTreeNode)
{
TREE_NODE* pLeftMax;
if(NULL == pTreeNode-> left_child && NULL == pTreeNode->right_child){
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = NULL;
else
pTreeNode->parent->right_child = NULL;
}
free(pTreeNode);
return TRUE;
}
3.2 删除的节点有左子树,没有右子树
测试用例1: 测试节点6
[cpp] view
plaincopy
/*
*
* 10 ======> 10
* / /
* 6 3
* /
* 3
*/
static void test10()
{
TREE_NODE* pTreeNode = NULL;
assert(TRUE == insert_node_into_tree(&pTreeNode, 10));
assert(TRUE == insert_node_into_tree(&pTreeNode, 6));
assert(TRUE == insert_node_into_tree(&pTreeNode, 3));
assert(TRUE == delete_node_from_tree(&pTreeNode, 6));
assert(3 == pTreeNode->left_child->data);
assert(pTreeNode = pTreeNode->left_child->parent);
free(pTreeNode->left_child);
free(pTreeNode);
}
测试用例2: 删除节点15
[cpp] view
plaincopy
/*
*
* 10 ======> 10
* \ \
* 15 12
* /
* 12
*/
static void test11()
{
TREE_NODE* pTreeNode = NULL;
assert(TRUE == insert_node_into_tree(&pTreeNode, 10));
assert(TRUE == insert_node_into_tree(&pTreeNode, 15));
assert(TRUE == insert_node_into_tree(&pTreeNode, 12));
assert(TRUE == delete_node_from_tree(&pTreeNode, 15));
assert(12 == pTreeNode->right_child->data);
assert(pTreeNode = pTreeNode->right_child->parent);
free(pTreeNode->right_child);
free(pTreeNode);
}
添加左子树不为空,右子树为空的处理代码,如下所示:
[cpp] view
plaincopy
STATUS _delete_node_from_tree(TREE_NODE* pTreeNode)
{
TREE_NODE* pLeftMax;
if(NULL == pTreeNode-> left_child && NULL == pTreeNode->right_child){
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = NULL;
else
pTreeNode->parent->right_child = NULL;
}else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){
pTreeNode->left_child->parent = pTreeNode->parent;
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->left_child;
else
pTreeNode->parent->right_child = pTreeNode->left_child;
}
free(pTreeNode);
return TRUE;
}
3.3 删除的节点左子树为空,右子树节点不为空
测试用例1: 删除数据6
[cpp] view
plaincopy
/*
*
* 10 ======> 10
* / /
* 6 8
* \
* 8
*/
static void test12()
{
TREE_NODE* pTreeNode = NULL;
assert(TRUE == insert_node_into_tree(&pTreeNode, 10));
assert(TRUE == insert_node_into_tree(&pTreeNode, 6));
assert(TRUE == insert_node_into_tree(&pTreeNode, 8));
assert(TRUE == delete_node_from_tree(&pTreeNode, 6));
assert(8 == pTreeNode->left_child->data);
assert(pTreeNode = pTreeNode->left_child->parent);
free(pTreeNode->left_child);
free(pTreeNode);
}
测试用例2: 删除数据15
[cpp] view
plaincopy
/*
*
* 10 ======> 10
* \ \
* 15 20
* \
* 20
*/
static void test13()
{
TREE_NODE* pTreeNode = NULL;
assert(TRUE == insert_node_into_tree(&pTreeNode, 10));
assert(TRUE == insert_node_into_tree(&pTreeNode, 15));
assert(TRUE == insert_node_into_tree(&pTreeNode, 20));
assert(TRUE == delete_node_from_tree(&pTreeNode, 15));
assert(20 == pTreeNode->right_child->data);
assert(pTreeNode = pTreeNode->right_child->parent);
free(pTreeNode->right_child);
free(pTreeNode);
}
添加左子树为空,右子树不为空的处理情形。代码如下:
[cpp] view
plaincopy
STATUS _delete_node_from_tree(TREE_NODE* pTreeNode)
{
TREE_NODE* pLeftMax;
if(NULL == pTreeNode-> left_child && NULL == pTreeNode->right_child){
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = NULL;
else
pTreeNode->parent->right_child = NULL;
}else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){
pTreeNode->left_child->parent = pTreeNode->parent;
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->left_child;
else
pTreeNode->parent->right_child = pTreeNode->left_child;
}else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){
pTreeNode->right_child->parent = pTreeNode->parent;
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->right_child;
else
pTreeNode->parent->right_child = pTreeNode->right_child;
}
free(pTreeNode);
return TRUE;
}
3.4 删除的节点左右子树均不为空,不过又要分为两种情形:
1) 左节点是删除节点左侧的最大节点 (删除节点6)
[cpp] view
plaincopy
/*
*
* 10 ======> 10
* / /
* 6 5
* / \ \
* 5 8 8
*/
static void test14()
{
TREE_NODE* pTreeNode = NULL;
assert(TRUE == insert_node_into_tree(&pTreeNode, 10));
assert(TRUE == insert_node_into_tree(&pTreeNode, 6));
assert(TRUE == insert_node_into_tree(&pTreeNode, 5));
assert(TRUE == insert_node_into_tree(&pTreeNode, 8));
assert(TRUE == delete_node_from_tree(&pTreeNode, 6));
assert(5 == pTreeNode->left_child->data);
assert(pTreeNode = pTreeNode->left_child->parent);
assert( 8 == pTreeNode->left_child->right_child->data);
assert(pTreeNode->left_child = pTreeNode->left_child->right_child->parent);
free(pTreeNode->left_child->right_child);
free(pTreeNode->left_child);
free(pTreeNode);
}
2) 左节点不是删除节点左侧的最大节点(删除节点5)
[cpp] view
plaincopy
/*
*
* 10 ======> 10
* / /
* 5 4
* / \ / \
* 2 6 2 6
* \
* 4
*/
static void test15()
{
TREE_NODE* pTreeNode = NULL;
assert(TRUE == insert_node_into_tree(&pTreeNode, 10));
assert(TRUE == insert_node_into_tree(&pTreeNode, 5));
assert(TRUE == insert_node_into_tree(&pTreeNode, 2));
assert(TRUE == insert_node_into_tree(&pTreeNode, 4));
assert(TRUE == insert_node_into_tree(&pTreeNode, 6));
assert(TRUE == delete_node_from_tree(&pTreeNode, 5));
assert(4 == pTreeNode->left_child->data);
assert(NULL == pTreeNode->left_child->left_child->right_child);
free(pTreeNode->left_child->left_child);
free(pTreeNode->left_child->right_child);
free(pTreeNode->left_child);
free(pTreeNode);
}
那么针对这两种类型,我们的代码究竟应该怎么处理呢?
[cpp] view
plaincopy
STATUS _delete_node_from_tree(TREE_NODE* pTreeNode)
{
TREE_NODE* pLeftMax;
if(NULL == pTreeNode-> left_child && NULL == pTreeNode->right_child){
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = NULL;
else
pTreeNode->parent->right_child = NULL;
}else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){
pTreeNode->left_child->parent = pTreeNode->parent;
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->left_child;
else
pTreeNode->parent->right_child = pTreeNode->left_child;
}else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){
pTreeNode->right_child->parent = pTreeNode->parent;
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->right_child;
else
pTreeNode->parent->right_child = pTreeNode->right_child;
}else{
pLeftMax = find_max_node(pTreeNode->left_child);
if(pLeftMax == pTreeNode->left_child){
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->left_child;
else
pTreeNode->parent->right_child = pTreeNode->left_child;
pTreeNode->left_child->parent = pTreeNode->parent;
pTreeNode->left_child->right_child = pTreeNode->right_child;
pTreeNode->right_child->parent = pTreeNode-> left_child;
}else{
pTreeNode->data = pLeftMax->data;
pLeftMax->parent->right_child = pLeftMax->left_child;
pLeftMax->left_child->parent = pLeftMax->parent;
pTreeNode = pLeftMax;
}
}
free(pTreeNode);
return TRUE;
}
结束总结:
上面的过程记录了我们的代码是怎么一步一步走过来的。最后我们给出一份完整的节点删除代码:
[cpp] view
plaincopy
STATUS _delete_node_from_tree(TREE_NODE* pTreeNode)
{
TREE_NODE* pLeftMax;
if(NULL == pTreeNode-> left_child && NULL == pTreeNode->right_child){
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = NULL;
else
pTreeNode->parent->right_child = NULL;
}else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){
pTreeNode->left_child->parent = pTreeNode->parent;
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->left_child;
else
pTreeNode->parent->right_child = pTreeNode->left_child;
}else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){
pTreeNode->right_child->parent = pTreeNode->parent;
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->right_child;
else
pTreeNode->parent->right_child = pTreeNode->right_child;
}else{
pLeftMax = find_max_node(pTreeNode->left_child);
if(pLeftMax == pTreeNode->left_child){
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->left_child;
else
pTreeNode->parent->right_child = pTreeNode->left_child;
pTreeNode->left_child->parent = pTreeNode->parent;
pTreeNode->left_child->right_child = pTreeNode->right_child;
pTreeNode->right_child->parent = pTreeNode-> left_child;
}else{
pTreeNode->data = pLeftMax->data;
pLeftMax->parent->right_child = pLeftMax->left_child;
pLeftMax->left_child->parent = pLeftMax->parent;
pTreeNode = pLeftMax;
}
}
free(pTreeNode);
return TRUE;
}
STATUS delete_node_from_tree(TREE_NODE** ppTreeNode, int data)
{
TREE_NODE* pTreeNode;
TREE_NODE* pLeftMax;
if(NULL == ppTreeNode || NULL == *ppTreeNode)
return FALSE;
pTreeNode = find_data_in_tree_node(*ppTreeNode, data);
if(NULL == pTreeNode)
return FALSE;
if(*ppTreeNode == pTreeNode){
if(NULL == pTreeNode->left_child && NULL == pTreeNode->right_child){
*ppTreeNode = NULL;
}else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){
*ppTreeNode = pTreeNode->left_child;
pTreeNode->left_child->parent = NULL;
}else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){
*ppTreeNode = pTreeNode->right_child;
pTreeNode->right_child->parent = NULL;
}else{
pLeftMax = find_max_node(pTreeNode->left_child);
if(pLeftMax == pTreeNode->left_child){
*ppTreeNode = pTreeNode->left_child;
(*ppTreeNode)->right_child = pTreeNode->right_child;
(*ppTreeNode)->right_child->parent = *ppTreeNode;
(*ppTreeNode)->parent = NULL;
}else{
pTreeNode->data = pLeftMax->data;
pLeftMax->parent->right_child = pLeftMax->left_child;
pLeftMax->left_child->parent = pLeftMax->parent;
pTreeNode = pLeftMax;
}
}
free(pTreeNode);
return TRUE;
}
return _delete_node_from_tree(pTreeNode);
}
3 普通节点的删除
3.1 删除的节点没有左子树,也没有右子树
测试用例1: 删除节点6
[cpp] view
plaincopy
/*
*
* 10 ======> 10
* / \ \
* 6 15 15
*
*/
static void test8()
{
TREE_NODE* pTreeNode = NULL;
assert(TRUE == insert_node_into_tree(&pTreeNode, 10));
assert(TRUE == insert_node_into_tree(&pTreeNode, 6));
assert(6 == pTreeNode->left_child->data);
assert(TRUE == insert_node_into_tree(&pTreeNode, 15));
assert(TRUE == delete_node_from_tree(&pTreeNode, 6));
assert(NULL == pTreeNode->left_child);
free(pTreeNode->right_child);
free(pTreeNode);
}
测试用例2: 删除节点15
[cpp] view
plaincopy
/*
*
* 10 ======> 10
* / \ /
* 6 15 6
*
*/
static void test9()
{
TREE_NODE* pTreeNode = NULL;
assert(TRUE == insert_node_into_tree(&pTreeNode, 10));
assert(TRUE == insert_node_into_tree(&pTreeNode, 6));
assert(TRUE == insert_node_into_tree(&pTreeNode, 15));
assert(15 == pTreeNode->right_child->data);
assert(TRUE == delete_node_from_tree(&pTreeNode, 15));
assert(NULL == pTreeNode->right_child);
free(pTreeNode->right_child);
free(pTreeNode);
}
那么代码应该怎么编写呢?
[cpp] view
plaincopy
STATUS _delete_node_from_tree(TREE_NODE* pTreeNode)
{
TREE_NODE* pLeftMax;
if(NULL == pTreeNode-> left_child && NULL == pTreeNode->right_child){
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = NULL;
else
pTreeNode->parent->right_child = NULL;
}
free(pTreeNode);
return TRUE;
}
3.2 删除的节点有左子树,没有右子树
测试用例1: 测试节点6
[cpp] view
plaincopy
/*
*
* 10 ======> 10
* / /
* 6 3
* /
* 3
*/
static void test10()
{
TREE_NODE* pTreeNode = NULL;
assert(TRUE == insert_node_into_tree(&pTreeNode, 10));
assert(TRUE == insert_node_into_tree(&pTreeNode, 6));
assert(TRUE == insert_node_into_tree(&pTreeNode, 3));
assert(TRUE == delete_node_from_tree(&pTreeNode, 6));
assert(3 == pTreeNode->left_child->data);
assert(pTreeNode = pTreeNode->left_child->parent);
free(pTreeNode->left_child);
free(pTreeNode);
}
测试用例2: 删除节点15
[cpp] view
plaincopy
/*
*
* 10 ======> 10
* \ \
* 15 12
* /
* 12
*/
static void test11()
{
TREE_NODE* pTreeNode = NULL;
assert(TRUE == insert_node_into_tree(&pTreeNode, 10));
assert(TRUE == insert_node_into_tree(&pTreeNode, 15));
assert(TRUE == insert_node_into_tree(&pTreeNode, 12));
assert(TRUE == delete_node_from_tree(&pTreeNode, 15));
assert(12 == pTreeNode->right_child->data);
assert(pTreeNode = pTreeNode->right_child->parent);
free(pTreeNode->right_child);
free(pTreeNode);
}
添加左子树不为空,右子树为空的处理代码,如下所示:
[cpp] view
plaincopy
STATUS _delete_node_from_tree(TREE_NODE* pTreeNode)
{
TREE_NODE* pLeftMax;
if(NULL == pTreeNode-> left_child && NULL == pTreeNode->right_child){
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = NULL;
else
pTreeNode->parent->right_child = NULL;
}else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){
pTreeNode->left_child->parent = pTreeNode->parent;
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->left_child;
else
pTreeNode->parent->right_child = pTreeNode->left_child;
}
free(pTreeNode);
return TRUE;
}
3.3 删除的节点左子树为空,右子树节点不为空
测试用例1: 删除数据6
[cpp] view
plaincopy
/*
*
* 10 ======> 10
* / /
* 6 8
* \
* 8
*/
static void test12()
{
TREE_NODE* pTreeNode = NULL;
assert(TRUE == insert_node_into_tree(&pTreeNode, 10));
assert(TRUE == insert_node_into_tree(&pTreeNode, 6));
assert(TRUE == insert_node_into_tree(&pTreeNode, 8));
assert(TRUE == delete_node_from_tree(&pTreeNode, 6));
assert(8 == pTreeNode->left_child->data);
assert(pTreeNode = pTreeNode->left_child->parent);
free(pTreeNode->left_child);
free(pTreeNode);
}
测试用例2: 删除数据15
[cpp] view
plaincopy
/*
*
* 10 ======> 10
* \ \
* 15 20
* \
* 20
*/
static void test13()
{
TREE_NODE* pTreeNode = NULL;
assert(TRUE == insert_node_into_tree(&pTreeNode, 10));
assert(TRUE == insert_node_into_tree(&pTreeNode, 15));
assert(TRUE == insert_node_into_tree(&pTreeNode, 20));
assert(TRUE == delete_node_from_tree(&pTreeNode, 15));
assert(20 == pTreeNode->right_child->data);
assert(pTreeNode = pTreeNode->right_child->parent);
free(pTreeNode->right_child);
free(pTreeNode);
}
添加左子树为空,右子树不为空的处理情形。代码如下:
[cpp] view
plaincopy
STATUS _delete_node_from_tree(TREE_NODE* pTreeNode)
{
TREE_NODE* pLeftMax;
if(NULL == pTreeNode-> left_child && NULL == pTreeNode->right_child){
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = NULL;
else
pTreeNode->parent->right_child = NULL;
}else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){
pTreeNode->left_child->parent = pTreeNode->parent;
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->left_child;
else
pTreeNode->parent->right_child = pTreeNode->left_child;
}else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){
pTreeNode->right_child->parent = pTreeNode->parent;
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->right_child;
else
pTreeNode->parent->right_child = pTreeNode->right_child;
}
free(pTreeNode);
return TRUE;
}
3.4 删除的节点左右子树均不为空,不过又要分为两种情形:
1) 左节点是删除节点左侧的最大节点 (删除节点6)
[cpp] view
plaincopy
/*
*
* 10 ======> 10
* / /
* 6 5
* / \ \
* 5 8 8
*/
static void test14()
{
TREE_NODE* pTreeNode = NULL;
assert(TRUE == insert_node_into_tree(&pTreeNode, 10));
assert(TRUE == insert_node_into_tree(&pTreeNode, 6));
assert(TRUE == insert_node_into_tree(&pTreeNode, 5));
assert(TRUE == insert_node_into_tree(&pTreeNode, 8));
assert(TRUE == delete_node_from_tree(&pTreeNode, 6));
assert(5 == pTreeNode->left_child->data);
assert(pTreeNode = pTreeNode->left_child->parent);
assert( 8 == pTreeNode->left_child->right_child->data);
assert(pTreeNode->left_child = pTreeNode->left_child->right_child->parent);
free(pTreeNode->left_child->right_child);
free(pTreeNode->left_child);
free(pTreeNode);
}
2) 左节点不是删除节点左侧的最大节点(删除节点5)
[cpp] view
plaincopy
/*
*
* 10 ======> 10
* / /
* 5 4
* / \ / \
* 2 6 2 6
* \
* 4
*/
static void test15()
{
TREE_NODE* pTreeNode = NULL;
assert(TRUE == insert_node_into_tree(&pTreeNode, 10));
assert(TRUE == insert_node_into_tree(&pTreeNode, 5));
assert(TRUE == insert_node_into_tree(&pTreeNode, 2));
assert(TRUE == insert_node_into_tree(&pTreeNode, 4));
assert(TRUE == insert_node_into_tree(&pTreeNode, 6));
assert(TRUE == delete_node_from_tree(&pTreeNode, 5));
assert(4 == pTreeNode->left_child->data);
assert(NULL == pTreeNode->left_child->left_child->right_child);
free(pTreeNode->left_child->left_child);
free(pTreeNode->left_child->right_child);
free(pTreeNode->left_child);
free(pTreeNode);
}
那么针对这两种类型,我们的代码究竟应该怎么处理呢?
[cpp] view
plaincopy
STATUS _delete_node_from_tree(TREE_NODE* pTreeNode)
{
TREE_NODE* pLeftMax;
if(NULL == pTreeNode-> left_child && NULL == pTreeNode->right_child){
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = NULL;
else
pTreeNode->parent->right_child = NULL;
}else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){
pTreeNode->left_child->parent = pTreeNode->parent;
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->left_child;
else
pTreeNode->parent->right_child = pTreeNode->left_child;
}else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){
pTreeNode->right_child->parent = pTreeNode->parent;
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->right_child;
else
pTreeNode->parent->right_child = pTreeNode->right_child;
}else{
pLeftMax = find_max_node(pTreeNode->left_child);
if(pLeftMax == pTreeNode->left_child){
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->left_child;
else
pTreeNode->parent->right_child = pTreeNode->left_child;
pTreeNode->left_child->parent = pTreeNode->parent;
pTreeNode->left_child->right_child = pTreeNode->right_child;
pTreeNode->right_child->parent = pTreeNode-> left_child;
}else{
pTreeNode->data = pLeftMax->data;
pLeftMax->parent->right_child = pLeftMax->left_child;
pLeftMax->left_child->parent = pLeftMax->parent;
pTreeNode = pLeftMax;
}
}
free(pTreeNode);
return TRUE;
}
结束总结:
上面的过程记录了我们的代码是怎么一步一步走过来的。最后我们给出一份完整的节点删除代码:
[cpp] view
plaincopy
STATUS _delete_node_from_tree(TREE_NODE* pTreeNode)
{
TREE_NODE* pLeftMax;
if(NULL == pTreeNode-> left_child && NULL == pTreeNode->right_child){
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = NULL;
else
pTreeNode->parent->right_child = NULL;
}else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){
pTreeNode->left_child->parent = pTreeNode->parent;
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->left_child;
else
pTreeNode->parent->right_child = pTreeNode->left_child;
}else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){
pTreeNode->right_child->parent = pTreeNode->parent;
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->right_child;
else
pTreeNode->parent->right_child = pTreeNode->right_child;
}else{
pLeftMax = find_max_node(pTreeNode->left_child);
if(pLeftMax == pTreeNode->left_child){
if(pTreeNode == pTreeNode->parent->left_child)
pTreeNode->parent->left_child = pTreeNode->left_child;
else
pTreeNode->parent->right_child = pTreeNode->left_child;
pTreeNode->left_child->parent = pTreeNode->parent;
pTreeNode->left_child->right_child = pTreeNode->right_child;
pTreeNode->right_child->parent = pTreeNode-> left_child;
}else{
pTreeNode->data = pLeftMax->data;
pLeftMax->parent->right_child = pLeftMax->left_child;
pLeftMax->left_child->parent = pLeftMax->parent;
pTreeNode = pLeftMax;
}
}
free(pTreeNode);
return TRUE;
}
STATUS delete_node_from_tree(TREE_NODE** ppTreeNode, int data)
{
TREE_NODE* pTreeNode;
TREE_NODE* pLeftMax;
if(NULL == ppTreeNode || NULL == *ppTreeNode)
return FALSE;
pTreeNode = find_data_in_tree_node(*ppTreeNode, data);
if(NULL == pTreeNode)
return FALSE;
if(*ppTreeNode == pTreeNode){
if(NULL == pTreeNode->left_child && NULL == pTreeNode->right_child){
*ppTreeNode = NULL;
}else if(NULL != pTreeNode->left_child && NULL == pTreeNode->right_child){
*ppTreeNode = pTreeNode->left_child;
pTreeNode->left_child->parent = NULL;
}else if(NULL == pTreeNode->left_child && NULL != pTreeNode->right_child){
*ppTreeNode = pTreeNode->right_child;
pTreeNode->right_child->parent = NULL;
}else{
pLeftMax = find_max_node(pTreeNode->left_child);
if(pLeftMax == pTreeNode->left_child){
*ppTreeNode = pTreeNode->left_child;
(*ppTreeNode)->right_child = pTreeNode->right_child;
(*ppTreeNode)->right_child->parent = *ppTreeNode;
(*ppTreeNode)->parent = NULL;
}else{
pTreeNode->data = pLeftMax->data;
pLeftMax->parent->right_child = pLeftMax->left_child;
pLeftMax->left_child->parent = pLeftMax->parent;
pTreeNode = pLeftMax;
}
}
free(pTreeNode);
return TRUE;
}
return _delete_node_from_tree(pTreeNode);
}
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- AVL树-自平衡二叉查找树(Java实现)
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- “百度与站长”更新:关于网站收录,删除,seo等
- 用vbs删除某些类型文件和磁盘空间报告的脚本
- QQ聊天记录删除了怎么恢复简单方法
- vbs删除注册表项的代码
- 迅速删除非法文件名的批处理代码
- 通过批处理实现删除运行、查找等处的历史记录的代码
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Shell中删除某些文件外所有文件的3个方法
- Lua教程(二):C++和Lua相互传递数据示例
- 删除文件提示文件正在被另一个人或程序使用的解决方法
- 关于.LDB文件 .ldb文件的产生 .ldb文件的删除方法
- asp 合并记录集并删除的sql语句
- SQLserver 数据库危险存储过程删除与恢复方法
- sql自增长设置与删除的深入分析