二叉搜索树

//BSTreeNode.h

​
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>

typedef int DataType;
typedef struct BSTreeNode
{
	struct BSTreeNode* _pLeft;
	struct BSTreeNode* _pRight;
	DataType _data;
}BSTNode,*pBSTNode;
//二叉搜索树的实现---循环
pBSTNode BuyBSTreeNode(DataType data);//创建二叉搜索树
void InitBSTree(pBSTNode* pRoot);//初始化二叉搜索树
int InsertBSTree(pBSTNode* pRoot, DataType data);//插入值为data的元素
void PreOrderBSTree(pBSTNode pRoot);//前序遍历二叉搜索树
void DeleteBSTree(pBSTNode* pRoot, DataType data);//删除值为data的元素
pBSTNode FindBSTree(pBSTNode pRoot, DataType data);//在二叉搜索树中查找值为data的结点
void DestroyBSTree(pBSTNode* pRoot);//销毁二叉搜索树
// 递归实现二叉搜索树中查找、插入和删除方法 
pBSTNode FindBSTreeNode(pBSTNode pRoot, DataType data);//递归查找
int InsertBSTreeNode(pBSTNode* pRoot, DataType data);//递归插入
void DeleteBSTreeNode(pBSTNode* pRoot, DataType data);//递归删除


​

//bstreenode.c

​
#define _CRT_SECURE_NO_WARNINGS 1
#include"BSTreeNode.h"

//二叉搜索树的实现---循环
pBSTNode BuyBSTreeNode(DataType data)//创建二叉搜索树
{
	pBSTNode pNewNode = (pBSTNode)malloc(sizeof(BSTNode));
	if (NULL == pNewNode)
	{
		return 0;
	}
	pNewNode->_data = data;
	pNewNode->_pLeft = NULL;
	pNewNode->_pRight = NULL;
	return pNewNode;
}
void InitBSTree(pBSTNode* pRoot)//初始化二叉搜索树
{
	assert(pRoot);
	*pRoot = NULL;
}
int InsertBSTree(pBSTNode* pRoot, DataType data)//插入值为data的元素
{
	//二叉搜索树为空,直接插入,返回true
	if (NULL == *pRoot)
	{
		*pRoot = BuyBSTreeNode(data);
		return 1;
	}
	//不为空,按二叉搜索树的性质查找插入位置,插入新结点
	//左不等于空,左子树结点的值<根结点的值
	//右不等于空,右子树结点的值>根节点的值
	pBSTNode pCur = *pRoot;
	pBSTNode pParent = NULL;
	while (pCur)
	{
		if (data < pCur->_data)
		{
			pParent = pCur;
			pCur = pCur->_pLeft;
		}
		else if (data>pCur->_data)
		{
			pParent = pCur;
			pCur = pCur->_pRight;
		}
		else
		{
			return 0;
		}
	}
	pCur = BuyBSTreeNode(data);
	if (pCur->_data < pParent->_data)
	{
		pParent->_pLeft = pCur;
	}
	else
	{
		pParent->_pRight = pCur;
	}
	return 1;
}
void PreOrderBSTree(pBSTNode pRoot)//前序遍历二叉搜素树
{
	if (pRoot)
	{
		PreOrderBSTree(pRoot->_pLeft);
		printf("%d", pRoot->_data);
		PreOrderBSTree(pRoot->_pRight);
	}
}
void DeleteBSTree(pBSTNode* pRoot, DataType data)//删除值为data的元素
{
	//首先查找元素是否在二叉搜索树中,不在,返回
	pBSTNode pCur = *pRoot;
	pBSTNode pParent = NULL;
	pBSTNode pDel = NULL;
	//定位
	while (pCur)
	{
		if (data < pCur->_data)
		{
			pParent = pCur;
			pCur = pCur->_pLeft;
		}
		else if (data>pCur->_data)
		{
			pParent = pCur;
			pCur = pCur->_pRight;
		}
		else
			break;
	}
	if (pCur)//如果pCur不为空,已经确定了pCur的位置,开始删除
	{
		//1.pCur无孩子 || 只有左孩子
		if (NULL == pCur->_pRight)//只有左孩子
		{
			if (pCur == *pRoot)//pCur为根节点
			{
				*pRoot = pCur->_pLeft;
			}
			else
			{
				if (pCur == pParent->_pLeft)//删除双亲的左孩子,双亲的左孩子指向pCur的左
				{
					pParent->_pLeft = pCur->_pLeft;
				}
				else//删除双亲的右孩子,双亲的右孩子指向pCur的左
				{
					pParent->_pRight = pCur->_pLeft;
				}
			}
		}
		//2.只有右孩子
		else if (NULL == pCur->_pLeft)
		{
			if (pCur == *pRoot)//pCur为根节点
			{
				*pRoot = pCur->_pRight;
			}
			else
			{
				if (pCur == pParent->_pLeft)//删除双亲的左孩子,双亲的左孩子指向pCur的右
				{
					pParent->_pLeft = pCur->_pRight;
				}
				else//删除双亲的右孩子,双亲的右孩子指向pCur的右
				{
					pParent->_pRight = pCur->_pRight;
				}
			}
		}
		//3.pCur既有左孩子又有右孩子
		else
		{
			pParent = pCur;
			pDel = pCur->_pRight;//在它的右子树中寻找中序的下一个结点,用它的值填补到被删除结点中,再来处理该结点的删除问题
			while (pDel->_pLeft)//中序查找第一个数
			{
				pParent = pDel;
				pDel = pDel->_pLeft;
			}
			pCur->_data = pDel->_data;//找到,进行替换
			if (pDel == pParent->_pLeft)
			{
				pParent->_pLeft = pCur->_pRight;
			}
			else
			{
				pParent->_pRight = pCur->_pRight;
			}
		}
		free(pDel);
	}
}
pBSTNode FindBSTree(pBSTNode pRoot, DataType data)//在二叉搜索树中查找值为data的结点
{
	assert(pRoot);
	pBSTNode pCur = pRoot;
	while (pCur)
	{
		if (data < pCur->_data)
		{
			pCur = pCur->_pLeft;
		}
		else if (data>pCur->_data)
		{
			pCur = pCur->_pRight;
		}
		else
		{
			return pCur;
		}
	}
	return NULL;
}
void DestroyBSTree(pBSTNode* pRoot)//销毁二叉搜索树
{
	if (*pRoot)
	{
		DestroyBSTree(&(*pRoot)->_pLeft);
		DestroyBSTree(&(*pRoot)->_pRight);
		free(*pRoot);
	}
}

// 递归实现二叉搜索树中查找、插入和删除方法 
pBSTNode FindBSTreeNode(pBSTNode pRoot, DataType data)//递归查找
{
	if (NULL == pRoot)
	{
		return NULL;
	}
	if (data < pRoot->_data)
	{
		return FindBSTreeNode(pRoot->_pLeft,data);
	}
	else if (data>pRoot->_data)
	{
		return FindBSTreeNode(pRoot->_pRight, data);
	}
	else
	{
		return pRoot;
	}
}
int InsertBSTreeNode(pBSTNode* pRoot, DataType data)//递归插入
{
	//二叉搜索树为空,直接插入,返回true
	if (NULL == *pRoot)
	{
		*pRoot = BuyBSTreeNode(data);
		return 1;
	}
	if (data < (*pRoot)->_data)
	{
		return InsertBSTreeNode(&(*pRoot)->_pLeft, data);
	}
	else if (data>(*pRoot)->_data)
	{
		return InsertBSTreeNode(&(*pRoot)->_pRight, data);
	}
	else
	{
		return 0;
	}
}
void DeleteBSTreeNode(pBSTNode* pRoot, DataType data)//递归删除
{
	//判树空
	if (NULL == *pRoot)
	{
		return;
	}
	//删除左孩子
	if (data < (*pRoot)->_data)
	{
		 DeleteBSTreeNode(&(*pRoot)->_pLeft, data);
	}
	//删除右孩子
	else if (data>(*pRoot)->_data)
	{
		 DeleteBSTreeNode(&(*pRoot)->_pRight, data);
	}
	//定位
	else
	{
		pBSTNode pDel = *pRoot;
		//只有左孩子
		if (NULL == pDel->_pRight)
		{
			(*pRoot) = (*pRoot)->_pLeft;
			free(pDel);
		}
		//只有右孩子
		else if (NULL == pDel->_pLeft)
		{
			(*pRoot) = (*pRoot)->_pRight;
			free(pDel);
		}
		//有左有右
		else
		{
			pDel = (*pRoot)->_pRight;
			while (pDel->_pLeft)
			{
				pDel = pDel->_pLeft;
			}
			pDel->_data = (*pRoot)->_data;
			DeleteBSTreeNode(&(*pRoot)->_pRight, pDel->_data);
		}
	}
}

​

//test.c

​
#define _CRT_SECURE_NO_WARNINGS 1
#include"BSTreeNode.h"
//二叉搜索树的实现---循环测试
void testBSTree()
{
	pBSTNode pRoot;
	int arr[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
	//初始化
	InitBSTree(&pRoot);
	//插入
	for (int i = 0; i < 10; i++)
	{
		InsertBSTree(&pRoot,arr[i]);
	}
	PreOrderBSTree(pRoot);
	printf("\n");
	//删除
	DeleteBSTree(&pRoot, 0);
	DeleteBSTree(&pRoot, 1);
	DeleteBSTree(&pRoot, 2);
	DeleteBSTree(&pRoot, 3);
	DeleteBSTree(&pRoot, 4);
	DeleteBSTree(&pRoot, 5);
	DeleteBSTree(&pRoot, 6);
	DeleteBSTree(&pRoot, 7);
	DeleteBSTree(&pRoot, 8);
	DeleteBSTree(&pRoot, 9);
	PreOrderBSTree(pRoot);
	printf("\n");
	//查找
	pBSTNode Find = NULL;
	Find = FindBSTree(pRoot, 2);
	if (Find)
	{
		printf("%d\n", Find->_data);
	}
	else
	{
		printf("%d\n", 2);
	}
	//销毁
	DestroyBSTree(&pRoot);
}
// 递归实现二叉搜索树中查找、插入和删除测试
void testBSTreeNode()
{
	pBSTNode pRoot;
	int arr[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
	//初始化
	InitBSTree(&pRoot);
	//插入
	for (int i = 0; i < 10; i++)
	{
		InsertBSTree(&pRoot, arr[i]);
	}
	PreOrderBSTree(pRoot);
	printf("\n");
	//查找
	pBSTNode Find = NULL;
	Find = FindBSTreeNode(pRoot, 2);
	if (Find)
	{
		printf("%d\n", Find->_data);
	}
	else
	{
		printf("%d\n", 2);
	}
	//插入
	for (int i = 0; i < 10; i++)
	{
		InsertBSTreeNode(&pRoot, arr[i]);
	}
	PreOrderBSTree(pRoot);
	printf("\n");
	//删除
	DeleteBSTreeNode(&pRoot, 0);
	DeleteBSTreeNode(&pRoot, 1);
	DeleteBSTreeNode(&pRoot, 2);
	DeleteBSTreeNode(&pRoot, 3);
	DeleteBSTreeNode(&pRoot, 4);
	DeleteBSTreeNode(&pRoot, 5);
	DeleteBSTreeNode(&pRoot, 6);
	DeleteBSTreeNode(&pRoot, 7);
	DeleteBSTreeNode(&pRoot, 8);
	DeleteBSTreeNode(&pRoot, 9);
	PreOrderBSTree(pRoot);
	printf("\n");
}

int main()
{
	//testBSTree();
	testBSTreeNode();
	system("pause");
	return 0;
}

​

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值