BST(二叉排序樹)的插入與刪除


值得一說的是刪除操作,刪除操作我們分為三種情況:

1.要刪的節點有兩個孩子:

  找到左子樹中的最大值或者右子樹中的最小值所對應的節點,記為node,並把node的值賦給要刪除的節點del,然后刪除node

實際上真正刪除的是node,del只是發生了一次值的替換。

為了方便理解和操作,我們把兩個孩子的情況放在最前面,這樣經過以上處理后,該節點就會變成情況2或者情況3 ,接下愛這行這兩種情況的代碼。

2.要刪的節點有一個孩子

r判斷要刪除的節點del是其父親father的左孩子還是右孩子,以是father的左孩子為例,del是father的左孩子,接下來判斷del是否有左孩子,

如果有,則father的左孩子變成del的左孩子,如果沒有,則father的左孩子變成del的右孩子。

3.要刪的節點沒有孩子

即為當情況2 del的左孩子右孩子為空的時候

#include<stdio.h>
#include<stdlib.h>
typedef struct Tree
{
	int data;
	Tree*right;
	Tree*left;
}BinaryTree;
void insert(BinaryTree **p,int e)
{
	BinaryTree *temp=(BinaryTree*)malloc(sizeof(BinaryTree));
	temp->data=e;
	temp->left=NULL;
	temp->right=NULL;

	if(*p==NULL)
	{
		*p=temp;
		return ;
	}
	BinaryTree*root=*p;
	while(1)
	{
		if(e<root->data)
		{
			if(root->left)
			{
				root=root->left;
			}
			else
			{
				root->left=temp;
				break;//完成插入操作了
			}

		}
		else if(e>root->data)
		{
			if(root->right)
			{
				root=root->right;

			}
			else
			{
				root->right=temp;
				break;
			}
		}
	}
}
void  FindNode(BinaryTree* p,BinaryTree **del,BinaryTree**father, int e)//我們在刪除操作中不僅需要知道要刪除哪個節點,還要知道要刪除節點的父親
{                                          //return無法返回兩個值,要實現返回兩個值,我們在這里采用二級指針
	while(1)                                                                    //實際上也可以通過結構體封裝來完成同時返回兩個值
	{
		if(e<p->data)
		{  
			*father=p;//每次都記錄一下父親
			p=p->left;
		}
		else if(e>p->data)
		{
			*father=p;
			p=p->right;
		}
		else if(e==p->data)
		{
			*del=p;return ;	
		}
	}
}
void deleteNode(BinaryTree **p,int e)//
{
	if(*p==NULL) return ;
	BinaryTree *root=*p;
	BinaryTree *del=NULL;
	BinaryTree *father=NULL;
	BinaryTree *pmark=NULL;
	FindNode(root,&del,&father,e);
	if(del->left&&del->right)
	{
		pmark=del;//標記要刪除的點
		father=del;
		del=del->left;
		while(del->right)
		{
			father=del;
			del=del->right;
		}
		pmark->data=del->data;
	}
	//接下來分析有一個或者沒有孩子的情況
	//被刪節點 是根
	if(father==NULL)//??
	{
		*p=del->left?del->left:del->right;
		free(del);
		return ;
	}
	else
	{//不用在寫判斷條件了,走到這說明就是一個或者沒有孩子,只需要判斷是哪邊的孩子就可
		if(del==father->left)
			father->left=del->left?del->left:del->right;
		else if(del==father->right)
			father->right=del->left?del->left:del->right;
		free(del);

	}
}
void inorder(BinaryTree *p)
{
	if(p==NULL) return ;
	//遞歸要有結束條件
	inorder(p->left);
	printf(" %d ",p->data);
	inorder(p->right);
}
void preorder(BinaryTree *p)
{
	if(p==NULL) return ;
	//遞歸要有結束條件
	
	printf(" %d ",p->data);
	preorder(p->left);
	preorder(p->right);
}
int main()
{
	int m;
	BinaryTree *p=NULL;
	int a[10];
	int i;
	scanf("%d",&m);
	for(i=0;i<m;i++)
	{
		scanf("%d",&a[i]);
	}
	for(i=0;i<m;i++)
	{
		insert(&p,a[i]);
	}
	preorder(p);
	printf("\n");
	inorder(p);
	deleteNode(&p,9);
	preorder(p);
	printf("\n");
	inorder(p);
	return 0;
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM