二叉排序(搜索)树

这篇博客介绍了二叉排序树的基本操作,包括如何插入新节点、删除节点以及进行前序遍历。插入节点时,根据节点值与当前节点的大小关系决定插入位置;删除节点时,考虑了三种不同情况:无子节点、一个子节点和两个子节点。此外,还提供了完整的C++代码实现。
摘要由CSDN通过智能技术生成

特点

每个顶点总是大于它的左孩子,小于它的右孩子。
插入新结点:沿着根节点开始,key大于当前结点就往右子树搜,小于当前结点就往右子树搜,如果等于,说明已经有该结点,插入失败,否则,一直到叶子结点,将当前结点插入对应位置称为新的叶子。
删除结点:先找有无结点p,若无,删除失败。若有,分为三种情况:
p只有左孩子,将左孩子链接到p的父结点,删除p;
p只有右孩子,将右孩子链接到p的父结点,删除p;
p有两个孩子,找到p的左孩子的最右孙子,或者p的右孩子的最左孙子,根据二叉排序树的特点可以知道这两个点最接近p,用它替换p仍然可以保持二叉排序树特性,只要将结点的值替换即可,然后删除用来替换的结点(删除方法同前两种情况)。

#include<iostream>
using namespace std;

typedef struct BiTNode
{
	int data;
	BiTNode* lchild, * rchild;
}BiTNode,*BiTree;

//创建二叉排序树
void Insert(BiTree* T, int key) //单个结点的插入函数,递归实现
{
	BiTree s;
	if (*T == NULL) //为空,找到根结点,插入
	{
		s = (BiTree)malloc(sizeof(BiTNode));
		s->data = key;
		s->lchild = NULL;
		s->rchild = NULL;
		*T = s;
	}
	else if (key < (*T)->data)//要插入的值大于当前结点,往左子树搜
		Insert(&((*T)->lchild), key);
	else if (key > (*T)->data)//大于当前结点,往右子树搜
		Insert(&((*T)->rchild), key);
}
void CreateBStree(BiTree* T)
{
	int key;
	*T = NULL;
	int a[10] = { 35 ,23, 45, 27 ,19, 12, 56, 66 ,18 ,32 };
	for(int i=0;i<10;i++)
	{
		Insert(T, a[i]);  //调用插入结点函数
	}
}

//前序遍历二叉树
void PreOrder(BiTree T)
{
	if (T==NULL)
		return;
	cout << T->data << " ";
	PreOrder(T->lchild);
	PreOrder(T->rchild);
}

//查找
//T:当前结点,key:键值,f:根结点,p:用于返回查找到的数据
bool BST_Search(BiTree T, int key, BiTree f,BiTree* p)
{
	if (!T)
	{
		*p = f;
		return false;
	}
	else if (key == T->data)
	{
		*p = T;
		return true;
	}
	else if (key < T->data)
		BST_Search(T->lchild, key, T, p);
	else
		BST_Search(T->rchild, key, T, p);
}

bool BST_Insert(BiTree* T, int key) 
{
	BiTree p, s;
	if (!BST_Search(*T, key, NULL, &p)) //查找不成功,返回p为最后一个比较的结点
	{
		s = (BiTree)malloc(sizeof(BiTNode));  //新的结点
		s->data = key;
		s->lchild = s->rchild = NULL;
		if (!p)  //返回空,排序树为空,s作为根结点
			*T = s;
		else if (key < p->data)  
			p->lchild = s;
		else
			p->rchild = s;
		return true;
	}
	else
		return false;
}

bool Delete(BiTree* p)
{
	BiTree q, s;
	if ((*p)->lchild == NULL)  //p左空,连上右子树
	{
		q = (*p);
		(*p) = (*p)->rchild;
		free(q);
	}
	else if ((*p)->rchild == NULL) //p右空,连上左子树
	{
		q = (*p);
		(*p) = (*p)->lchild;
		free(q);
	}
	else  //左右子树都不空
	{
		q = (*p);  //q存找到的p左子最右孩子的前驱
		s = (*p)->lchild;  //s存p的左子树中的最右结点
		while (s->rchild)
		{
			q = s; s = s->rchild;
		}
		(*p)->data = s->data;  //用s替换p
		if (q != (*p)) //此时s为q的左孩子,s无右孩子,把s的左孩子连到q的左子
			q->rchild = s->lchild;
		else  //此时s为q的右孩子,s无右孩子,把s的左孩子连接到q的右子即可
			q->lchild = s->lchild;
		free(s);
	}
	return true;
}

bool BST_Delete(BiTree* T, int key) //删除结点p
{
	BiTree p, q, s;
	s = (BiTree)malloc(sizeof(BiTNode));
	p = (BiTree)malloc(sizeof(BiTNode));
	q = (BiTree)malloc(sizeof(BiTNode));
	if (!T) //查找不成功
		return false;
	if ((*T)->data == key)
		return Delete(T);
	else if (key < (*T)->data)
		BST_Delete(&(*T)->lchild, key);
	else
		BST_Delete(&(*T)->rchild, key);
}

int main()
{
	BiTree T = NULL;
	//T = (BiTree*)malloc(sizeof(BiTree));
	int key = 18;
	CreateBStree(&T);
	cout << endl<<"删除"<<key<<"前" << endl;
	PreOrder(T);
	BST_Delete(&T,key);
	cout << endl<<"删除"<<key<<"后" << endl;
	PreOrder(T);
	BST_Insert(&T, key);
	cout << endl<<"插入"<<key<<"后"<<endl;
	PreOrder(T);
	return 0;
}

// 35 23 45 27 19 12 56 66 18 32 null
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值