C++递归及非递归实现二叉搜索树的创建,插入,查找,删除

博客主要介绍了二叉搜索树插入、查找、删除操作的实现方式,包括非递归和递归两种实现方法,还展示了测试结果和测试截图。

一.非递归实现二叉搜索树的插入,查找,删除

#include<iostream>
using namespace std;

template<class T>
struct BSTreeNode{
	BSTreeNode<T>* _pLeft;
	BSTreeNode<T>* _pRight;
	T _data;

	BSTreeNode(const T& data)
		: _pLeft(NULL)
		, _pRight(NULL)
		, _data(data)
	{}
};

template<class T>
class BSTree{
	typedef BSTreeNode<T> Node;
	typedef Node* PNode;
public:
	BSTree()
		: _pRoot(NULL)
	{}
	bool Insert(const T& data)
	{
		if (NULL == _pRoot){
			_pRoot = new Node(data);
			return true;
		}
		PNode pCur = _pRoot;
		PNode 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 false;
		}
		pCur = new Node(data);
		if (data < pParent->_data)
			pParent->_pLeft = pCur;
		else
			pParent->_pRight = pCur;
		return true;
	}
	void Find(const T& data)
	{
		PNode pCur = _pRoot;
		while (pCur){
			if (pCur->_data == data)
				return pCur;
			else if (data < pCur->_data)
				pCur = pCur->_pLeft;
			else
				pCur = pCur->_pRight;
		}
		return NULL;
	}
	bool Delete(const T& data)
	{
		PNode pCur = _pRoot;
		PNode pParent = NULL;
		while (pCur){
			if (pCur->_data == data)
				break;
			else if (data > pCur->_data){
				pParent = pCur;
				pCur = pCur->_pRight;
			}
			else{
				pParent = pCur;
				pCur = pCur->_pLeft;
			}
		}
		if (pCur == NULL)
			return false;
		
		if (NULL == pCur->_pRight){
			if (pCur == _pRoot)
				_pRoot = pCur->_pLeft;
			else{
				if (pCur == pParent->_pLeft)
					pParent->_pLeft = pCur->_pLeft;
				else
					pParent->_pRight = pCur->_pLeft;
			}
		}
		else if (NULL == pCur->_pLeft){
			if (pCur == _pRoot)
				_pRoot = pCur->_pRight;
			else{
				if (pCur == pParent->_pRight)
					pParent->_pRight = pCur->_pRight;
				else
					pParent->_pLeft = pCur->_pRight;
			}
		}
		else{
			PNode pDel = pCur->_pRight;
			pParent = pCur;
			while (pDel->_pLeft){
				pParent = pDel;
				pDel = pDel->_pLeft;
			}
			pCur->_data = pDel->_pLeft;
			if (pDel==pParent->_pLeft)
				pParent->_pLeft = pDel->_pRight;
			else 
				pParent->_pRight = pDel->_pRight;

			pCur = pDel;
		}
		delete pCur;
		return true;
	}

	void InOrder(){
		cout << "InOrder:";
		_InOrder(_pRoot);
		cout << endl;
	}
private:
	void _InOrder(PNode pRoot)
	{
		if (pRoot){
			_InOrder(pRoot->_pLeft);
			cout << pRoot->_data << " ";
			_InOrder(pRoot->_pRight);
		}
	}

private:
	PNode _pRoot;
};


void test(){
	int arr[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
	BSTree<int> bs;
	for (size_t i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
		bs.Insert(arr[i]);
	bs.InOrder();
	bs.Delete(5);
	bs.InOrder();
}


int main(){
	test();
	return 0;
}

测试结果:

二.递归实现二叉搜索树的插入,查找,删除:

#include<iostream>
using namespace std;

template<class T>
struct BSTreeNode{
	BSTreeNode<T>* _pLeft;
	BSTreeNode<T>* _pRight;
	T _data;

	BSTreeNode(const T& data)
		: _pLeft(NULL)
		, _pRight(NULL)
		, _data(data)
	{}
};

template<class T>
class BSTree{
	typedef BSTreeNode<T> Node;
	typedef Node* PNode;
public:
	BSTree()
		: _pRoot(NULL)
	{}
	bool Insert(const T& data)
	{
		return _Insert(_pRoot, data);
	}
	PNode Find(const T& data)
	{
		_Find(_pRoot, data);
	}
	bool Delete(const T& data)
	{
		return _Delete(_pRoot, data);
	}
	void InOrder()
	{
		cout << "InOrder:";
		_InOrder(_pRoot);
		cout << endl;
	}
private:
	bool _Insert(PNode& pRoot, const T& data)
	{
		if (NULL == pRoot){
			pRoot = new Node(data);
			return true;
		}
		else{
			if (pRoot->_data == data)
				return false;
			else if (pRoot->_data > data)
				return _Insert(pRoot->_pLeft, data);
			else
				return _Insert(pRoot->_pRight, data);
		}
	}
	PNode _Find(PNode pRoot, const T& data)
	{
		if (NULL == pRoot)
			return NULL;
		else{
			if (data == pRoot->_data)
				return pRoot;
			else if (data > pRoot->_data)
				return _Find(pRoot->_pRight, data);
			else
				return _Find(pRoot->_pLeft, data);
		}
	}
	bool _Delete(PNode& pRoot, const T& data)
	{
		if (NULL == pRoot)
			return false;
		else{
			if (data > pRoot->_data)
				return _Delete(pRoot->_pRight, data);
			else if (data < pRoot->_data)
				return _Delete(pRoot->_pLeft, data);
			else{
				PNode pDel = pRoot;
				if (pRoot->_pRight == NULL){
					pRoot = pRoot->_pLeft;
					delete pDel;
					return true;
				}
				else if (pRoot->_pLeft == NULL){
					pRoot = pRoot->_pRight;
					delete pDel;
					return true;
				}
				else{
					pDel = pRoot->_pRight;
					while (pDel->_pLeft){
						pDel = pDel->_pLeft;
					}
					pRoot->_data = pDel->_data;
					return _Delete(pRoot->_pRight, pDel->_data);
				}
			}
		}
	}
	void _InOrder(PNode pRoot)
	{
		if (pRoot){
			_InOrder(pRoot->_pLeft);
			cout << pRoot->_data << " ";
			_InOrder(pRoot->_pRight);
		}
	}
	
private:
	PNode _pRoot;

};

void test(){
	int arr[] = { 5, 3, 4, 1, 7, 8, 2, 6, 0, 9 };
	BSTree<int> bs;
	for (size_t i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
		bs.Insert(arr[i]);
	bs.InOrder();
	bs.Delete(5);
	bs.InOrder();
}

int main(){
	test();
	return 0;
}

测试截图:

### 二叉搜索树插入操作实现C++实现二叉搜索树插入操作需要满足二叉搜索树的基本性质:**左子树的节点值小于根节点,右子树的节点值大于根节点**。插入操作可以通过 **非递归方式** 或 **递归方式** 实现,以确保新节点能够正确插入到合适的位置。 #### 非递归方式插入 非递归实现通过遍历树来寻找合适的插入位置。从根节点开始,根据新插入节点的键值与当前节点的比较结果,决定向左子树或右子树移动,直到找到空节点的位置进行插入。 ```cpp template <class K, typename V> bool BSTree<K, V>::Insert(const K& key, const V& value) { Node* newNode = new Node(key, value); if (_root == nullptr) { _root = newNode; return true; } Node* cur = _root; Node* parent = nullptr; while (cur) { parent = cur; if (key < cur->_key) { cur = cur->_left; } else if (key > cur->_key) { cur = cur->_right; } else { // 键值已存在,不插入重复值 delete newNode; return false; } } if (key < parent->_key) { parent->_left = newNode; } else { parent->_right = newNode; } return true; } ``` #### 递归方式插入 递归实现通过函数调用自身的方式查找插入位置,并在递归回溯过程中完成节点的插入操作。这种方式逻辑清晰,但需要注意递归深度堆栈溢出问题。 ```cpp template <class K, typename V> bool BSTree<K, V>::Insert(Node*& root, const K& key, const V& value) { if (root == nullptr) { root = new Node(key, value); return true; } if (key < root->_key) { return Insert(root->_left, key, value); } else if (key > root->_key) { return Insert(root->_right, key, value); } else { // 键值已存在,不插入重复值 return false; } } ``` 调用方式如下: ```cpp Insert(_root, key, value); ``` #### 插入操作的逻辑分析 插入操作的核心在于查找合适的空位置以保持二叉搜索树的结构。若树为空,则直接将新节点作为根节点。若树不为空,则按照左子树 `<` 根 `<` 右子树的规则进行查找[^2]。在插入过程中,若遇到键值相同的节点,则可以选择不插入以避免重复值,或者根据需求选择插入到左子树或右子树,但必须保持逻辑一致性[^4]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值