排序二叉树节点的删除

原创 2018年04月17日 20:26:48

首先先看看这个删除节点12后的树,还要保证该平衡二叉树的特性保持不变

删除节点详细分为三类:

第一类.所删除的节点是叶子节点,这样就可以先遍历这个树,然后找到需要删除的节点,把它free掉就好

第二类:就是所删除的节点只有一个左孩子,或者只有一个右孩子,则把该节点的孩子变为它父亲的孩子 ,然后删除这个结点

在这个例子把28删除,就是把30连接到12上

第三类:就是最麻烦的一类,假如我们要删除节点12,直接删除就会破坏了排序二叉树的结构,那么我们想到一个方法,就是把这类转换成第一类,那么重点来了,我们找到要删除的结点后,找到在这个节点左子树的最右的节点或者右子树的最左侧的节点,把这个节点的值覆盖到要删除的节点上,然后删除左子树的最右的节点或者右子树的最左侧的节点,

 我们看这个例子:要删除12 先找到以12位根的左子树的最右的节点 就是数字6 ,把6覆盖到节点·12,然后删除节点6

                           或者找到右子树的最左边的节点 就是该树上的28,把28覆盖到节点12上,再删除28,就变成了第二类删除

代码如下:核心函数Search 和 DelNode

#include<stdio.h>
#include<stdlib.h>

typedef struct node
{
	int nValue;
	struct node *pLeft;
	struct node *pRight;
}BinatyTree;

void InsertNode(BinatyTree **pTree,int nNum)
{
	BinatyTree *pTemp = NULL;
	pTemp = (BinatyTree*)malloc(sizeof(BinatyTree));
	pTemp->nValue = nNum;
	pTemp->pLeft = NULL;
	pTemp->pRight = NULL;

	//空树
	if(*pTree == NULL)
	{
		*pTree = pTemp;
		return;
	}

	//非空树
	BinatyTree *pNode = *pTree;

	while(1)
	{
		if(nNum > pNode->nValue)
		{
			//去右侧
			if(pNode->pRight == NULL)
			{
				pNode->pRight = pTemp;
				return;
			}
			
			//向右走
			pNode = pNode->pRight;
		}
		else if(nNum < pNode->nValue)
		{
			//去左侧
			if(pNode->pLeft == NULL)
			{
				pNode->pLeft = pTemp;
				return;
			}
			pNode = pNode->pLeft;
		}
		else
		{
			printf("数据错误.\n");
			return;
		}
	}
}

void CreateBST(int arr[],int nLength,BinatyTree **pTree)
{
	if(arr == NULL || nLength <=0)return;

	int i;
	for(i = 0;i<nLength;i++)
	{
		InsertNode(pTree,arr[i]);
	}
}

void Search(BinatyTree *pTree,int nNum,BinatyTree **pDel,BinatyTree **pFather)
{
	while(pTree != NULL)
	{
		if(pTree->nValue == nNum)
		{
			*pDel = pTree;
			return;
		}
		else if(pTree->nValue > nNum)
		{
			*pFather = pTree;
			pTree = pTree->pLeft;
		}
		else 
		{
			*pFather = pTree;
			pTree = pTree->pRight;
		}
	}
}


void DelNode(BinatyTree **pTree,int nNum)
{
	if(*pTree == NULL)return;

	//查找
	BinatyTree *pDel = NULL;
	BinatyTree *pFather = NULL;

	Search(*pTree,nNum,&pDel,&pFather);

	if(pDel == NULL)return;

	//分析情况
	//两个
	BinatyTree *pMark = NULL;
	if(pDel->pLeft != NULL && pDel->pRight!= NULL)
	{
		//找左的最右
		pMark = pDel;

		//向左走一步
		pFather = pDel;
		pDel = pDel->pLeft;

		while(pDel->pRight != NULL)
		{
			pFather = pDel;
			pDel = pDel->pRight;
		}

		//值覆盖
		pMark->nValue = pDel->nValue;
	}

	//被删除节点是根节点
	if(pFather == NULL)
	{
		*pTree = pDel->pLeft ? pDel->pLeft : pDel->pRight;
		free(pDel);
		pDel = NULL;
		return;
	}

	//被删除节点非根
	if(pDel == pFather->pLeft)
	{
		pFather->pLeft = pDel->pLeft ? pDel->pLeft:pDel->pRight;
		free(pDel);
		pDel = NULL;
		return;
	}
	else
	{
		pFather->pRight = pDel->pLeft ? pDel->pLeft:pDel->pRight;
		free(pDel);
		pDel = NULL;
		return;
	}
}

void Traversal(BinatyTree *pTree)
{
	if(pTree == NULL)return;
	Traversal(pTree->pLeft);
	printf("%d ",pTree->nValue);
	Traversal(pTree->pRight);
}

int main()
{
	int arr[] = {10,38,2,100,80,15,1,8,16};
	BinatyTree *pTree = NULL;
	CreateBST(arr,sizeof(arr)/sizeof(arr[0]),&pTree);
	Traversal(pTree);
	printf("\n");
	DelNode(&pTree,10);
	Traversal(pTree);
	return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/aaa_cainiao_66666/article/details/79979966

删除排序二叉树的一个节点

  • 2012年05月26日 18:18
  • 3KB
  • 下载

javascript实现二叉树排序,前中后序遍历,最大最小值特定值查询以及删除节点

二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值; (2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值...
  • theoneEmperor
  • theoneEmperor
  • 2017-11-24 22:22:13
  • 170

排序二叉树删除

相比较节点的添加,平衡二叉树的删除要复杂一些。因为在删除的过程中,你要考虑到不同的情况,针对每一种不同的情况,你要有针对性的反应和调整。所以在代码编写的过程中,我们可以一边写代码,一边写测试用例。编写...
  • chenhao172013
  • chenhao172013
  • 2015-12-22 14:06:46
  • 314

二叉排序树的创建,插入,遍历,节点删除,整个删除的封装

#include using namespace std; typedef struct BSTree { int key; struct BSTree *LChild , *RChild; }...
  • m0_37907835
  • m0_37907835
  • 2018-01-04 13:13:07
  • 59

二叉排序树节点删除(c++)

二叉树是数据结构中一个重要的概念,而在二叉排序树的操作中,节点删除又相对较为复杂。本文把自己写的算法做一些总结,同时希望能够和大家进行交流。 首先我们要明白二叉排序树的性质: 一、二叉排序树是每个节点...
  • zhangyueyang520
  • zhangyueyang520
  • 2015-06-16 15:59:00
  • 1450

排序二叉树的建立、插入、删除、查找

/* 名称:排序二叉树的建立、插入、删除、查找 说明:对于排序二叉树来说,其创建、插入和查找的算法差不多。简单来说,就是小了往左,大了往右。 对于二叉排序树的删除来说,稍微要复...
  • plm199513100
  • plm199513100
  • 2017-12-03 16:33:34
  • 114

删除排序二叉树的节点

原题(LeetCode)Given a root node reference of a BST and a key, delete the node with the given key in th...
  • WittyCollegeStudent
  • WittyCollegeStudent
  • 2017-03-12 19:38:14
  • 199

算法:二叉排序树的删除节点策略及其图形化(二叉树查找)

二叉排序树(BST,Binary Sort Tree)具有这样的性质:对于二叉树中的任意节点,如果它有左子树或右子树,则该节点的数据成员大于左子树所有节点的数据成员,且小于右子树所有节点的数据成员。排...
  • Simba888888
  • Simba888888
  • 2013-05-05 23:06:03
  • 5378

Java实现二叉排序树的插入、查找、删除

import java.util.Random; /** * 二叉排序树(又称二叉查找树) * (1)可以是一颗空树 * (2)若左子树不空,则左子树上所有的结点的值均小于她的根节点...
  • u010829118
  • u010829118
  • 2014-08-17 08:48:17
  • 4389

【蓝桥杯】横向打印排序二叉树

算法思想都写在注释里面了,语文表达方面一直是硬伤,若有措辞不当的地方望互相交流。 代码看的一位犇的,原代码没有算法思想讲述和代码注释,我表示我只是进行注释的弱渣。 #include #in...
  • u011669700
  • u011669700
  • 2014-03-09 16:45:49
  • 2585
收藏助手
不良信息举报
您举报文章:排序二叉树节点的删除
举报原因:
原因补充:

(最多只允许输入30个字)