【数据结构】二叉搜索树的基本操作

  二叉搜索树也称为二叉排序树,具有以下性质:

1.若它的左子树不为空,则左子树上所有结点的值都小于根节点的值;

2.若它的右子树不为空,则右子树上所有节点的值都小于根节点的值;

3.它的左右子树均是二叉搜索树。

  本篇正是利用二叉搜索树的这些性质实现了查找节点、插入节点以及删除节点的基本操作(递归及循环实现)。

头文件

BinarySearchTree.h

# ifndef __BINARYSEARCHTREE_H__
# define __BINARYSEARCHTREE_H__

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

typedef int DataType;

typedef struct BSTree
{
	DataType data;
	struct BSTree * pLeft;
	struct BSTree * pRight;
}BSTree, * pBSTree;

int BSTreeInsert(pBSTree * pRoot, DataType data); // (循环实现)在二叉搜索树中插入数据,若插入数据成功则返回0,失败则返回-1
int BSTreeInsertRecursion(pBSTree * pRoot, DataType data); // (递归实现)在二叉搜索树中插入数据,若插入数据成功则返回0,失败则返回-1
int BSTreeFind(pBSTree pRoot, DataType data); // (循环实现)在二叉搜索树中查找某个数据,找到返回0,没找到返回-1
int BSTreeFindRecursion(pBSTree pRoot, DataType data); // (递归实现)在二叉搜索树中查找某个数据,找到返回0,没找到返回-1
int BSTreeRemove(pBSTree * pRoot, DataType data); // (循环实现)在二叉搜索树中删除某个数据,删除成功则返回0,失败则返回-1
int BSTreeRemoveRecursion(pBSTree * pRoot, DataType data); // (递归实现)在二叉搜索树中删除某个数据,删除成功则返回0,失败则返回-1
void BSTreeInOrder(pBSTree pRoot); // 中序遍历(递归)

# endif // __BINARYSEARCHTREE_H__

难点剖析

删除结点

  当找到需要删除的结点时,分情况讨论即可。

1.左孩子为空

2.右孩子为空

3.左右孩子均为空

4.左右孩子均不为空

  a.替换左子树中最大的;

  b.替换右子树中最小的。

实际上,左右孩子均为空这种情况可以归为1或者2处理即可,是个特例。综上,分三种情况讨论即可。

源代码

BinarySearchTree.c

#define _CRT_SECURE_NO_WARNINGS 1

/*
* Copyright (c) 2018, code farmer from sust
* All rights reserved.
*
* 文件名称:BinarySearchTree.c
* 功能:二叉搜索树的基本操作内部实现细节
*
* 当前版本:V1.0
* 作者:sustzc
* 完成日期:2018年6月21日15:06:25
*/

# include "BinarySearchTree.h"

/*
*	函数名称:CreateTreeNode
*
*	函数功能:创建新的结点
*
*	入口参数:data
*
*	出口参数:pNewNode
*
*	返回类型:pBSTree
*/

pBSTree CreateTreeNode(DataType data)
{
	pBSTree pNewNode = (pBSTree)malloc(sizeof(BSTree));
	assert(pNewNode);

	pNewNode->data  = data;
	pNewNode->pLeft = pNewNode->pRight = NULL;

	return pNewNode;
}

/*
*	函数名称:BSTreeInsert
*
*	函数功能:(循环实现)在二叉搜索树中插入数据,若插入数据成功则返回0,失败(data在树中)则返回-1
*
*	入口参数:pRoot, data
*
*	出口参数:0 or -1
*
*	返回类型:int
*/

int BSTreeInsert(pBSTree * pRoot, DataType data)
{
	if (NULL == *pRoot)
	{
		*pRoot = CreateTreeNode(data);

		return 0;
	}
	else
	{
		pBSTree pCur = *pRoot;
		pBSTree pParent = NULL;

		while (NULL != pCur)
		{
			pParent = pCur;

			if (data == pCur->data)
			{
				return -1;
			}
			else if (data < pCur->data)
				{
					pCur = pCur->pLeft;
				}
				else
				{
					pCur = pCur->pRight;
				}
		}

		if (data < pParent->data)
		{
			pParent->pLeft = CreateTreeNode(data);
		}
		else if (data > pParent->data)
			{
				pParent->pRight = CreateTreeNode(data);
			}
			else
			{
				;	
			}
	}
	
	return 0;
}


/*
*	函数名称:BSTreeInsertRecursion
*
*	函数功能:(递归实现)在二叉搜索树中插入数据,若插入数据成功则返回0,失败(data在树中)则返回-1
*
*	入口参数:pRoot, data
*
*	出口参数:0 or -1
*
*	返回类型:int
*/

int BSTreeInsertRecursion(pBSTree * pRoot, DataType data)
{
	if (NULL == *pRoot)
	{
		*pRoot = CreateTreeNode(data);

		return 0;
	}
	else
	{
		if (data == (*pRoot)->data)
		{
			return -1;
		}
		else if (data < (*pRoot)->data)
			{
				return BSTreeInsertRecursion(&((*pRoot)->pLeft), data);
			}
			else
			{
				return BSTreeInsertRecursion(&((*pRoot)->pRight), data);
			}
	}
	
	return 0;
}

/*
*	函数名称:BSTreeFind
*
*	函数功能:(循环实现)在二叉搜索树中查找某个数据,找到返回0,没找到返回-1
*
*	入口参数:pRoot, data
*
*	出口参数:0 or -1
*
*	返回类型:int
*/

int BSTreeFind(pBSTree pRoot, DataType data)
{
	if (NULL == pRoot)
	{
		return -1;
	}
	else
	{
		pBSTree pCur = pRoot;

		while (NULL != pCur)
		{
			if (data == pCur->data)
			{
				return 0;
			}
			else if (data < pCur->data)
				{
					pCur = pCur->pLeft;
				}
				else
				{
					pCur = pCur->pRight;
				}
		}
	}
	
	return -1;
}

/*
*	函数名称:BSTreeFind
*
*	函数功能:(递归实现)在二叉搜索树中查找某个数据,找到返回0,没找到返回-1
*
*	入口参数:pRoot, data
*
*	出口参数:0 or -1
*
*	返回类型:int
*/

int BSTreeFindRecursion(pBSTree pRoot, DataType data)
{
	if (NULL == pRoot)
	{
		return -1;
	}
	else if (data == pRoot->data)
		{
			return 0;
		}
		else if (data < pRoot->data)
			{
				return BSTreeFindRecursion(pRoot->pLeft, data);
			}
			else
			{
				return BSTreeFindRecursion(pRoot->pRight, data);
			}
}

/*
*	函数名称:BSTreeRemove
*
*	函数功能:(循环实现)在二叉搜索树中删除某个数据,删除成功返回0,失败返回-1(data不在树中)
*
*	入口参数:pRoot, data
*
*	出口参数:0 or -1
*
*	返回类型:int
*/

int BSTreeRemove(pBSTree * pRoot, DataType data)
{
	pBSTree pCur = *pRoot;
	pBSTree pParent = NULL;
	pBSTree pDelParent = NULL;

	while (NULL != pCur)
	{
		if (data == pCur->data)
		{
			//左孩子为空
			if (NULL == pCur->pLeft)
			{
				//此时的pCur不是根节点
				if (NULL != pParent)
				{
					if (data < pParent->data)
					{
						pParent->pLeft = pCur->pRight;
					}
					else
					{
						pParent->pRight = pCur->pRight;
					}
				}
				else
				{
					*pRoot = pCur->pRight;
				}

				free(pCur);
			}
			//右孩子为空
			else if (NULL == pCur->pRight)
				{
					if (NULL != pParent)
					{
						if (data < pParent->data)
						{
							pParent->pLeft = pCur->pLeft;
						}
						else
						{
							pParent->pRight = pCur->pLeft;
						}
					}
					else
					{
						*pRoot = pCur->pLeft;
					}

					free(pCur);
				}
				//左右孩子均不为空(替换法),用右子树中最小的替换
				else
				{
					//pBSTree pDel = pCur->pRight;
					//pDelParent = pCur;

					//while (NULL != pDel->pLeft)
					//{
					//	pDelParent = pDel;
					//	pDel = pDel->pLeft;
					//}

					//pCur->data = pDel->data;
					//pDel->data = data;
					//
					//pCur = pCur->pRight;
					
					pBSTree pDel = pCur->pRight;
					pDelParent = pCur;

					while (NULL != pDel->pLeft)
					{
						pDelParent = pDel;
						pDel = pDel->pLeft;
					}

					pCur->data = pDel->data;

					if (pCur == pDelParent)
					{
						pDelParent->pRight = pDel->pRight;
					}
					else
					{
						pDelParent->pLeft = pDel->pRight;
					}

					free(pDel);
				}

			return 0;
		}
		else 
		{
			pParent = pCur;
		}
			
		if (data < pCur->data)
		{
			pCur = pCur->pLeft;
		}
		else
		{
			pCur = pCur->pRight;
		}
	}

	return -1;
}

/*
*	函数名称:BSTreeRemoveRecursion
*
*	函数功能:(递归实现)在二叉搜索树中删除某个数据,删除成功返回0,失败返回-1(data不在树中)
*
*	入口参数:pRoot, data
*
*	出口参数:0 or -1
*
*	返回类型:int
*/

int BSTreeRemoveRecursion(pBSTree * pRoot, DataType data)
{
	if (NULL == *pRoot)
	{
		return -1;
	}
	else if (data < (*pRoot)->data)
		{
			return 	BSTreeRemoveRecursion(&((*pRoot)->pLeft), data);
		}
		else if (data > (*pRoot)->data)
			{
				return 	BSTreeRemoveRecursion(&((*pRoot)->pRight), data);
			}
			else
			{
				pBSTree pFree = *pRoot;
				//左孩子为空
				if (NULL == (*pRoot)->pLeft)
				{
					*pRoot = (*pRoot)->pRight;
					
					free(pFree);

					return 0;
				}
				//右孩子为空
				else if (NULL == (*pRoot)->pRight)
					{
						*pRoot = (*pRoot)->pLeft;
					
						free(pFree);

						return 0;
					}
					//左右孩子均不为空
					else
					{
						pBSTree pDel = (*pRoot)->pRight;

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

						//替换
						(*pRoot)->data = pDel->data;

						BSTreeRemoveRecursion(&((*pRoot)->pRight), pDel->data);

						return 0;
					}
			}
}

/*
*	函数名称:BSTreeInOrder
*
*	函数功能:中序遍历(递归)
*
*	入口参数:pRoot
*
*	出口参数:void
*
*	返回类型:void
*/

void BSTreeInOrder(pBSTree pRoot)
{
	if (NULL == pRoot)
	{
		return;
	}
	else
	{
		;
	}

	BSTreeInOrder(pRoot->pLeft);
	printf("%d ", pRoot->data);
	BSTreeInOrder(pRoot->pRight);

	return;
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1

/*
* Copyright (c) 2018, code farmer from sust
* All rights reserved.
*
* 文件名称:test.c
* 功能:测试二叉搜索树的基本操作
*
* 当前版本:V1.0
* 作者:sustzc
* 完成日期:2018年6月21日15:07:37
*/

# include "BinarySearchTree.h"

/*
*	函数名称:main
*
*	函数功能:测试主程序
*
*	入口参数:void
*
*	出口参数:0
*
*	返回类型:int
*/

int main(void)
{
	pBSTree pRoot = NULL;
	int i = 0;

	/*BSTreeInsert(&pRoot, 5);
	BSTreeInsert(&pRoot, 2);
	BSTreeInsert(&pRoot, 3);
	BSTreeInsert(&pRoot, 8);
	BSTreeInsert(&pRoot, 9);
	BSTreeInsert(&pRoot, 5);*/
	
	BSTreeInsertRecursion(&pRoot, 5);
	BSTreeInsertRecursion(&pRoot, 2);
	BSTreeInsertRecursion(&pRoot, 3);
	BSTreeInsertRecursion(&pRoot, 8);
	BSTreeInsertRecursion(&pRoot, 9);
	BSTreeInsertRecursion(&pRoot, 5);

	printf("中序遍历二叉树(递归):\n");
	BSTreeInOrder(pRoot);

	printf("\n\n查找数据(循环):\n");

	for (i = 0; i < 10; i++)
	{
		printf("查找数据: %d, 查找结果: %d\n", i, BSTreeFind(pRoot, i));
	}

	printf("\n查找数据(递归):\n");

	for (i = 0; i < 10; i++)
	{
		printf("查找数据: %d, 查找结果: %d\n", i, BSTreeFindRecursion(pRoot, i));
	}

	/*BSTreeRemove(&pRoot, 2);
	printf("\n中序遍历二叉树(递归):\n");
	BSTreeInOrder(pRoot);
	BSTreeRemove(&pRoot, 3);
	printf("\n中序遍历二叉树(递归):\n");
	BSTreeInOrder(pRoot);
	BSTreeRemove(&pRoot, 8);
	printf("\n中序遍历二叉树(递归):\n");
	BSTreeInOrder(pRoot);
	BSTreeRemove(&pRoot, 9);
	printf("\n中序遍历二叉树(递归):\n");
	BSTreeInOrder(pRoot);
	BSTreeRemove(&pRoot, 5);
	printf("\n中序遍历二叉树(递归):\n");
	BSTreeInOrder(pRoot);
	printf("\n");*/

	BSTreeRemoveRecursion(&pRoot, 2);
	printf("\n中序遍历二叉树(递归):\n");
	BSTreeInOrder(pRoot);
	BSTreeRemoveRecursion(&pRoot, 3);
	printf("\n中序遍历二叉树(递归):\n");
	BSTreeInOrder(pRoot);
	BSTreeRemoveRecursion(&pRoot, 8);
	printf("\n中序遍历二叉树(递归):\n");
	BSTreeInOrder(pRoot);
	BSTreeRemoveRecursion(&pRoot, 9);
	printf("\n中序遍历二叉树(递归):\n");
	BSTreeInOrder(pRoot);
	BSTreeRemoveRecursion(&pRoot, 5);
	printf("\n中序遍历二叉树(递归):\n");
	BSTreeInOrder(pRoot);
	printf("\n");

	return 0;
}

输出结果


猜你喜欢

转载自blog.csdn.net/sustzc/article/details/80840999