数据结构 二叉排序树 查入 搜索 删除

本文详细介绍二叉排序树的基本概念及其插入、查找与删除算法的实现。通过具体实例演示了如何利用二叉排序树进行数据组织,并给出了完整的C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

动态查找:动态查找不仅要查找结点,而且还要不断地插入和删除结点,当表采用顺序结构时,这需要花费大量的时间用于结点的移动,效率很低。这里采用树表的形式,树表本身可以动态建立,树表主要有二叉排序树,平衡二叉树,B-树和B+树等。

二叉排序树的特点是:lchild <= root <= rchild,对此树中序遍历就可以找到一组有序的数组。二叉树的复杂度一般为O(log n ),但在特殊情况为O(n)

这里要强调一点就是二叉排序树删除时要分两种情况,一种被删除点没有左子树,另外一种是有左子树。详细请见源代码

#include <iostream.h>
#include <string.h>

typedef int KeyType;
#define NUM 11
class BinStree;
class BinSTreeNode
{
public:
	KeyType key;
	BinSTreeNode *lchild;
	BinSTreeNode *rchild;
	BinSTreeNode()
	{
		lchild = NULL;
		rchild = NULL;
	}
};

class BinSTree
{
public:
	BinSTreeNode *root;
	BinSTree()
	{
		root = NULL;
	}
	~BinSTree()
	{
//		DeleteTree();
	}
	BinSTreeNode *BSTreeSearch( BinSTreeNode *bt, KeyType k, BinSTreeNode *&p );
	void BSTreeInsert( BinSTreeNode *&bt, KeyType k );  
	int BSTreeDelete( BinSTreeNode *&bt, KeyType k );
//	void Destroy( BinSTreeNode *current );
//	void DeleteTree()
//	{
//		Destroy( root );
//		root = NULL;
//	}
	bool IsEmpty()
	{
		return root == NULL;
	}
};

/**
  *  二叉树排序查找算法
  *  在根指针为bt的二叉排序树中查找元素k的节点,若查找成功,则返回指向该节点的指针
  *  参数p指向查找到的结点,否则返回空指针,参数p指向k应插入的父结点
  */
BinSTreeNode* BinSTree::BSTreeSearch( BinSTreeNode *bt, KeyType k, BinSTreeNode *&p )
{
	BinSTreeNode *q = NULL;
	q = bt;
	while( bt )
	{
		q = bt;
		if( bt->key == k )
		{
			p = bt;
			return( bt );
		}
		if( bt->key > k )
			bt = bt->lchild;
		else
			bt = bt->rchild;
	}
	p = q;
	return( bt );
}

/**
  *  二叉排序树的插入节点算法
  *  bt指向二叉排序树的根结点,插入元素k的结点
  */
void BinSTree::BSTreeInsert( BinSTreeNode *&bt, KeyType k )
{
	BinSTreeNode *p = NULL, *q;
	q = bt;
	if( BSTreeSearch( q, k, p ) == NULL )
	{
		BinSTreeNode *r = new BinSTreeNode;
		r->key = k;
		r->lchild = r->rchild = NULL;
		if( q == NULL )
		{
			bt = r;         //被插入节点做为树的根节点
		}
		if( p && k < p->key )
			p->lchild = r;
		else if( p )
			p->rchild = r;
	}
}

/**
  * 二叉排序树的删除结点算法
  * 在二叉排序树中删除元素为k的结点,*bt指向二叉排序树的根节点
  * 删除成功返回1,不成功返回0.
  */
int BinSTree::BSTreeDelete( BinSTreeNode *&bt, KeyType k )
{
	BinSTreeNode *f, *p, *q, *s;
	p = bt;
	f = NULL;
	//查找关键字为k的结点,同时将此结点的双亲找出来
	while( p && p->key != k )
	{
		f = p;
		if( p->key > k )
			p = p->lchild;
		else
			p = p->rchild;
	}
	if( p == NULL )   //找不到待删除的结点时返回
		return 0;
	if( p->lchild == NULL )  //待删除结点的左子树为空
	{
		if( f == NULL )  //待删除结点为根节点
			bt = p->rchild;
		else if( f->lchild == p )  //待删结点是其双亲结点的左节点
			f->lchild = p->rchild;
		else
			f->rchild = p->rchild;  //待删结点是其双亲结点的右节点
		delete p;

	}
	else                    //待删除结点有左子树
	{
		q = p;
		s = p->lchild;
		while( s->rchild )  //在待删除结点的左子树中查找最右下结点
		{
			q = s;
			s = s->rchild;
		}
		if( q == p )
			q->lchild = s->lchild;
		else
			q->rchild = s->lchild;
		
		p->key = s->key;
		delete s;
	}
	return 1;
}
int main( void )
{
	int a[NUM] = { 34, 18, 76, 13, 52, 82, 16, 67, 58, 73, 72 };
	int i;
	BinSTree bst;
	BinSTreeNode *pBt = NULL, *p = NULL, *pT = NULL;

	for( i = 0; i < NUM; i++ )
	{
		bst.BSTreeInsert( pBt, a[i] ); //创建二叉排序树
	}
	pT = bst.BSTreeSearch( pBt, 52, p ); //搜索排序二叉树
	bst.BSTreeDelete( pBt, 13 );   //删除无左孩子的情况
	bst.BSTreeDelete( pBt, 76 );   //删除有左孩子的情况
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值