搜索树——c++实现

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


搜索树

搜索树适用于字典描述,与跳表和散列相比,二叉搜索树和平衡搜索树使用更加灵活,在最坏的情况下性能有保证。

二叉搜索树:

是一棵二叉树,可能为空,非空的二叉搜索树满足以下特征:

1.每个元素都有唯一的关键字

2.根节点的左子树中,元素的关键字都小于根节点的关键字

3.根节点的右子树中,元素的关键字都大于根节点的关键字

4.根节点左右子树也都是二叉搜索树

在这里插入图片描述
a就不是二叉搜索树(不满足4),bc是二叉搜索树。

注: 有重复值的二叉搜索树, 小于–>小于等于


索引二叉搜索树:

源于普通的二叉搜索树,只是在每个节点中添加一个leftSize域,表示该节点的左子树的元素个数:

在这里插入图片描述

二叉搜索树的操作:

1. 搜索:

假设需要查找的关键字为theKey,则先从根节点开始查找,如果为空,则树不包含任何元素;否则,将theKey和根节点的关键字进行比较,如果等于,则查找成功,如果theKey小于根节点的关键字,则查找左子树即可,否则,查找右子树。

2. 插入

假设要在二叉搜索树中插入一个元素,首先通过查找来确定,要插入的元素的关键字在树中是否存在,如果存在,则用插入元素的value覆盖掉原来的value,否则,将元素插入树中:

3. 删除

要考虑三种情况:

1.要删除的节点是树叶:

2.要删除的节点有一棵子树

3.要删除的节点有两棵子树


二叉搜索树的实现

// 定义二叉搜索树树
#ifndef BSTREE_H
#define BSTREE_H
#include <algorithm> 
#include <iostream>
using namespace std;
 
// 定义二叉搜索树的节点
template<typename K=int, typename V=int>   // key: value类型的节点 
struct BSTreeNode
{
	BSTreeNode* leftchild;
	BSTreeNode* rightchild;
	K key;
	V value;
	
	BSTreeNode(K& theKey, V& theValue)
	{
		key = theKey;
		value = theValue;
		leftchild = NULL;
		rightchild = NULL;
	}
}; 
 
template<typename K, typename V>
class BSTree
{
	typedef BSTreeNode<K, V> BSTreeNode;
	private:
	BSTreeNode* root;     // 二叉搜索树的根节点
	int treeSize;
	void destory(BSTreeNode* mroot);       // 删除二叉树的所有节点  // 析构函数 
	BSTreeNode* find(K theKey, BSTreeNode* mroot); 
	void insert(K theKey, V theValue, BSTreeNode* mroot);
	void remove(K theKey, BSTreeNode* mroot); // 删除特定的节点 
	void out_put(BSTree* mroot);
	 
	public:
	BSTree();
	~BSTree();
	// void destory(); 
	// 查找二叉树的节点
	BSTreeNode* find(K theKey);  // 参数:键值
	void insert(K theKey, V theValue);
	void remove(K theKey); 
	void out_put();
};
 
template<typename K, typename V>
void BSTree<K, V>::destory(BSTreeNode* mroot)
{
	// 删除所有节点   递归调用 
	if(mroot!=NULL)
	{
		destory(mroot->leftchild);
		destory(mroot->rightchild);
		delete mroot;
	}	 
}
 
 
template<typename K, typename V>
BSTree<K, V>::BSTree()
{
	treeSize = 0;
	root = NULL;
}
 
template<typename K, typename V> 
BSTree<K, V>::~BSTree()
{
	// 删除二叉树的节点
	destory(root); 
}
 
template<typename K, typename V>
BSTreeNode* BSTree<K, V>::find(K theKey)
{
	// 二叉搜索树的查找函数
	// 根据关键字查找:
	return find(theKey, root); 
}
 
template<typename K, typename V>
BSTreeNode* BSTree<K, V>::find(K theKey, BSTreeNode* mroot)
{
	if(mroot != NULL)
	{
		if(mroot->key==theKey)
		{
			return mroot;
		}
		else if(mroot->key>theKey)   // 搜索左子树
		{
			return find(theKey, mroot->leftchild);    // 递归的方法 
		} 
		else   // 搜索右子树
		{
			return find(theKey, mroot->rightchild);
		} 
	}
	return NULL;  // 没有找到 
}
 
template<typename K, typename V>
void BSTree<K, V>::insert(K theKey, V theValue, BSTreeNode* mroot)
{
	// NULL
	
	if(mroot==NULL)
	{
		mroot = new BSTreeNode(theKey, theValue);
		return;    // 递归结束    
	}
	
	if(mroot->key==theKey)   // 关键字已经存在 
	{
		mroot->value = theValue;
		return;    // 结束递归 
	} 
	else if(theKey < mroot->key)    // 插入左子树
	{
		insert(theKey, theValue, mroot->leftchild);
	} 
	
	else   // 插入右子树 
	{
		insert(theKey, theValue, mroot->rightchild); 
	}
	
}
 
template<typename K, typename V>
void BSTree<K, V>::insert(K theKey, V theValue)
{
	insert(theKey, theValue, root);
}
 
template<typename K, typename V>
void BSTree<K, V>::remove(K theKey, BSTreeNode* mroot)
{
	/* 
	if(mroot==NULL)   // 结束的条件 
	{
		cout << "No such node" << endl; 
		return;
	}
	*/
	 
	// 只有一个节点
	if(mroot->leftchild==NULL && mroot->rightchild==NULL)   // 最底层的节点 
	{
		if(root->key==theKey)   // 是要查找的节点 
		{
			delete mroot;
			mroot = NULL;
			return;
		}
		
	}
	
	if(theKey<mroot->key)    // 搜索左子树 
	{
		remove(theKey, mroot->leftchild); 
	} 
	else if(theKey>mroot->key)
	{
		remove(theKey, mroot->rightchild);   // 搜索右子树 
	}
	else     // 相等。且不是最底层的节点  
	{
		BSTreeNode* del = NULL;    // 临时的指针
		if(mroot->leftchild==NULL)   // 只有右孩子 
		{
			del = mroot;
			mroot = mroot->rightchild;   // 取右孩子
			delete del;
			del = NULL;
			return; 
		} 
		else if(mroot->rightchild==NULL)   // 只有左孩子
		{
			del = mroot;
			mroot = mroot->leftchild;
			delete del;
			del = NULL;
			return;
		}
		else   // 要删除的节点有左右子树 
		{
			BSTreeNode* rightFirst = mroot->rightchild;   // 获取要删除的节点的右孩子
			while(rightFirst->leftchild!=NULL)
			{
				rightFirst = rightFirst->leftchild;
			} 
			
			// 交换
			// 将要删除的节点交换到最底层 
			swap(mroot->key, rightFirst->key);
			swap(mroot->value, rightFirst->value); 
			remove(theKey, mroot->rightchild);     // 接着删除
		    return;   // ? 
		} 
	} 
	
}
 
template<typename K, typename V>
void BSTree<K, V>::remove(K theKey)
{
	remove(theKey, root);
}
 
template<typename K, typename V>
void BSTree<K, V>::out_put(BSTreeNode* mroot)
{
	if(mroot==NULL)
	{
		return;
	}
	out_put(mroot->leftchild);
	cout << "key: " << mroot->key << " value: " << mroot->value << " ";
	out_put(mroot->rightchild);
}
 
template<typename K, typename V>
void BSTree<K, V>::out_put() 
{
	out_put(root);
} 
 
#endif
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值