C++ 实现二叉搜索树—BSTree

二叉搜索树的概念以及特性想必大家都有所了解,在这里主要讨论它的实现。
具体算法思路见代码注释。

//测试环境为VS2013

#include <iostream>
#include <stdlib.h>
using namespace std;

template <class T>

struct BSTNode{
	BSTNode(const T& val = T())
	:_left(nullptr)
	, _right(nullptr)
	, _data(val)
	{}
	BSTNode<T>* _left;
	BSTNode<T>* _right;
	T _data;
};

template <class T>
class BSTree{
public:
	typedef BSTNode<T> Node;
	BSTree(Node* root = nullptr)
		:_root(root)
	{}

	Node* Copy(Node* root)
	{
		if (root){
			Node* newNode = new Node(root->_data);
			newNode->_left = Copy(root->_left);
			newNode->_right = Copy(root->_right);
			return newNode;
		}
		else
			return nullptr;
	}

	BSTree(const BSTree<T>& bst)
	{
		_root = Copy(bst._root);
	}

	BSTree<T>& operator=(const BSTree<T>& bst)
	{
		if (this != &bst){
			if (_root){
				//假如已经有了bst1,现在欲将bst2赋值给bst1,
				//即 bst1 = bst2
				//就应该先将原先的bst1释放了,再将bst2赋给它,否则会造成内存泄漏
				Destory(_root);
			}
			_root = Copy(bst._root);
		}
		return *this;
	}

	void Destory(Node* root)
	{
		if (root){
			Destory(root->_left);
			Destory(root->_right);
			delete root;
			root = nullptr;
		}
	}
	~BSTree()
	{
		if (_root)
			Destory(_root);
	}


	//查找
	Node* Find(const T& x)
	{
		if (_root == nullptr)
			return nullptr;
		Node* cur = _root;
		while (cur != nullptr){
			if (cur->_data == x)
				return cur;
			else if (x > cur->_data)
				cur = cur->_right;
			else
				cur = cur->_left;
		}
		return nullptr;
	}

	//插入
	bool Insert(const T& x)
	{
		if (_root == nullptr){
			_root = new Node(x);
			return true;
		}

		Node* cur = _root;
		Node* parent = nullptr;

		while (cur != nullptr){
			if (cur->_data == x)
				//二叉搜索树里不能有相同节点,所以就返回错误
				return false;
			else if (x > cur->_data){
				parent = cur;
				cur = cur->_right;
			}
			else{
				parent = cur;
				cur = cur->_left;
			}
		}
		//将x的值存入节点中
		//再分析新节点值与parent节点值的大小关系
		//若x大于parent值,就将parent的右指针链接cur;反之链接左指针
		cur = new Node(x);
		if (x > parent->_data)
			parent->_right = cur;
		else
			parent->_left = cur;
		return true;
	}
	
	//删除
	bool Erase(const T& x)
	{
		if (_root == nullptr)
			//若为空树,则删除失败
			return false;
		Node* cur = _root;
		Node* parent = nullptr;
		//要做删除,先做查找,即先找到要删除的节点
		while (cur != nullptr){
			if (cur->_data == x)
				break;
			else if (x < cur->_data){
				parent = cur;
				cur = cur->_left;
			}
			else{
				parent = cur;
				cur = cur->_right;
			}
		}
		//没找到
		if (cur == nullptr)
			return false;
		//1.删除的是叶子节点
		if (cur->_left == nullptr && cur->_right == nullptr){
			if (cur != _root){
				//若删除的不是根节点
				if (parent->_left == cur)
					parent->_left = nullptr;
				else
					parent->_right = nullptr;
			}
			else
				//删除的是根
				_root = nullptr;

			delete cur;
			cur = nullptr;
		}

		//2.孩子节点不完整(有左无右,有右无左)

		//要删除的节点只有右孩子
		else if (cur->_left == nullptr){
			if (cur != _root){
				if (parent->_left == cur)
					parent->_left = cur->_right;
				else
					parent->_right = cur->_right;
			}
			else{
				_root = cur->_right;
			}
			delete cur;
			cur = nullptr;
		}
		//要删除的节点只有左孩子 ***************************
		else if (cur->_right == nullptr){
			if (cur != _root){
				if (parent->_left == cur)
					parent->_left = cur->_left;
				else
					parent->_right = cur->_left;
			}
			else{
				_root = cur->_left;
			}
			delete cur;
			cur = nullptr;
		}

		//若要删除的节点的左右孩子均完整
		else{
			//在左边找个最大的(或者在右边找最小的)
			Node* leftMost = cur->_left;
			parent = cur;
			//找左边最大的
			//因为要找左边最大的,就要往cur的左孩子的right找
			while (leftMost->_right){
				parent = leftMost;
				leftMost = leftMost->_right;
			}
			//找到了
			//置换两个节点的值,然后将leftMost节点删除
			cur->_data = leftMost->_data;
			if (parent->_right == leftMost)
				parent->_right = leftMost->_left;
			else
				parent->_left = leftMost->_left;
			//删除节点
			delete leftMost;
			leftMost = nullptr;
		}
		return true;
	}


	//中序遍历
	void Inorder()
	{
		Print_Inorder(_root);
		cout << endl;
	}

	//打印
	void Print_Inorder(Node* root)
	{
		if (root != nullptr){
			Print_Inorder(root->_left);
			cout << root->_data << " ";
			Print_Inorder(root->_right);
		}
	}
private:
	Node* _root;
};

void Test()
{
	BSTree<int> bstree;

	bstree.Insert(0);
	bstree.Insert(1);
	bstree.Insert(2);
	bstree.Insert(3);
	bstree.Insert(4);
	bstree.Insert(5);
	bstree.Insert(6);
	bstree.Insert(7);
	bstree.Insert(8);
	bstree.Insert(9);
	cout << "bstree:";
	bstree.Inorder();

	/*bstree.Inorder();
	bstree.Erase(5);
	bstree.Inorder();
	bstree.Erase(4);
	bstree.Inorder();
	bstree.Erase(8);
	bstree.Erase(9);
	bstree.Inorder();
	bstree.Erase(7);
	bstree.Inorder();
	bstree.Erase(2);
	bstree.Erase(1);
	bstree.Inorder();*/

	BSTree<int> bst;
	bst.Insert(0);
	bst.Insert(1);
	bst.Insert(2);
	bst.Insert(3);
	bst.Insert(4);
	bst.Insert(5);
	cout << "bst:";
	bst.Inorder();
	//BSTree<int> bst (bstree);
	//bst.Inorder();

	bst = bstree;
	cout << "赋值: ";
	bst.Inorder();
}
int main()
{
	Test();
	system("pause");
	return 0;
}

结果:
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章