算法系列—二叉查找树

在二叉树中,每个结点只能有一个父结点(根结点除外),而且每个结点都会有左右两条链接,分别指向自己的左子结点和又子结点。


结点结构定义:

template <class T>
class Node
{
public:
	T data;
	int size;	//以该节点为根的节点总数
	Node* lson;
	Node* rson;

	Node(T data,int size)
	{
		this->data = data;
		this->size = size;
		this->lson = NULL;
		this->rson = NULL;
	}
};

二叉树类定义如下:

由于二叉树很多方法都用到了递归,所以我们设计一个public接口,通过重载来调用递归实现。


template<class T>
class BST
{
private:
	Node<T>* root;	//根节点
	//函数定义
	int size(Node<T> *x)	//返回以该节点为根节点数
	{
		if (x == NULL)
			return 0;
		else 
			return x->size;
	}
	void makeEmpty(Node<T>* &t);	//删除整个二叉树
	bool contains(const T&x, const Node<T>* t);	//是否包含x

	const Node<T>* findMin(Node<T> *t);	//寻找最小值
	const Node<T>* findMax(Node<T> *t);	//寻找最大值

	void insert(const T& x, Node<T>* &t);	//插入x

	void Delete ( Node<T>*& t, T x);	//删除x

	void printTreeInPrev(Node<T> *t);	//前序遍历打印
	void printTreeInMid(Node<T> *t);	//中序遍历打印
	void printTreeInPost(Node<T> *t);	//后序遍历打印
	int rank(T x, Node<T>* t);	//返回以x为根节点的子树中小于x的结点的数量
public:
	int size()
	{
		return size(root);
	}

	BST();
	BST(const BST& rhs);
	~BST();
	void makeEmpty();

	bool contains(const T& x);

	const T& findMin();
	const T& findMax();

	void insert(const T& x);

	void Delete(T x);

	void printTree(ORDER_MODE mode = ORDER_MODE_PREV);

	int rank(T x);
};

定义一个枚举类型,用于列举是前序遍历,中序遍历,还是后序遍历。

enum ORDER_MODE
{	//分别为前序,中序,后序
	ORDER_MODE_PREV = 0,
	ORDER_MODE_MID,
	ORDER_MODE_POST
};


以下是具体函数的实现:


构造函数和析构函数,以及清空二叉树empty函数的实现:


//构造与析构
template<class T>
BST<T>::BST()
{
	root = NULL;
}
template<class T>
BST<T>::BST(const BST& rhs)
{
	root = rhs.root;
}
template<class T>
BST<T>::~BST()
{
	makeEmpty();
}
template<class T>
void BST<T>::makeEmpty()
{
	makeEmpty(root);
}
template<class T>
void BST<T>::makeEmpty(Node<T>* &t)
{
	if(t)
	{
		makeEmpty(t->lson);
		makeEmpty(t->rson);
		delete t;
	}
	t = NULL;
}

contains函数:

template<class T>
bool BST<T>::contains(const T& x)
{
	return contains(x, root);
}
template<class T>
bool BST<T>::contains(const T& x, const Node<T>* t)
{
	if (t == NULL)
		return NULL;
	if (x < t->data)
		return contains(x, t->lson);
	else if (x > t->data)
		return contains(x, t->rson);
	else return true;
}


寻找最大值与最小值函数:

template<class T>
const T& BST<T>::findMin()
{
	return findMin(root)->data;
}
template<class T>
const Node<T>* BST<T>::findMin(Node<T> *t)
{
	if (t->lson == NULL)
		return t;
	return findMin(t->lson);
}
template<class T>
const T& BST<T>::findMax()
{
	return findMax(root)->data;
}
template<class T>
const Node<T>* BST<T>::findMax(Node<T> *t)
{
	if (t->rson == NULL)
		return t;
	return findMax(t->rson);
}

插入函数:

template<class T>
void BST<T>::insert(const T& x)
{
	insert(x, root);
}
template<class T>
void BST<T>::insert(const T& x, Node<T>* &t)
{
	if (t == NULL)
		t = new Node<T>(x, 1);
	if (x < t->data)
		insert(x, t->lson);
	else if (x > t->data)
		insert(x, t->rson);
	else    //如果相同,更新现在的值
		t->data = x;
	t->size = size(t->lson) + size(t->rson) + 1;
}


删除函数,此处要分为:被删除的元素有两个子结点,有左结点,有右结点,无子结点

template<class T>
void BST<T>::Delete(T x)
{
	Delete(root, x);
}

template<class T>
void BST<T>::Delete(Node<T>* &t,T x)
{
	if (t == NULL)
		return;
	if (x < t->data) {
		Delete(t->lson, x);
		t->size = size(t->lson) + size(t->rson) + 1;
	}
	else if (x > t->data)
	{
		Delete(t->rson, x);
		t->size = size(t->lson) + size(t->rson) + 1;
	}
	else
	{
		//找到了要删除的元素
		if(t->lson!=NULL && t->rson!=NULL)
		{
			t->data = findMin(t->rson)->data;
			Delete(t->rson, t->data);
			t->size = size(t->lson) + size(t->rson) + 1;
		}
		else
		{
			//此处有错误,日后修改
			//Node<T>* tmp = t;
			//t = (t->lson != NULL) ? t->lson : t->rson;
			//delete (tmp);
		}
	}	
}

printTree函数通过参数来分别调用不同的打印函数:

template<class T>
void BST<T>::printTree(ORDER_MODE mode)
{
	switch (mode)
	{
	case ORDER_MODE_PREV:
		printTreeInPrev(root);
		break;
	case ORDER_MODE_MID:
		printTreeInMid(root);
		break;
	case ORDER_MODE_POST:
		printTreeInPost(root);
		break;
	}
}

前序遍历,中序遍历,后序遍历的函数:

template<class T>
void BST<T>::printTreeInPrev(Node<T>* t)
{
	if (t)
	{
		std::cout << t->data;
		printTreeInPrev(t->lson);
		printTreeInPrev(t->rson);
	}
}

template<class T>
void BST<T>::printTreeInMid(Node<T>* t)
{
	if(t)
	{
		printTreeInMid(t->lson);
		std::cout << t->data;
		printTreeInMid(t->rson);
	}
}

template<class T>
void BST<T>::printTreeInPost(Node<T>* t)
{
	if(t)
	{
		printTreeInPost(t->lson);
		printTreeInPost(t->rson);
		std::cout << t->data;
	}
}

rank小于x结点的结点数量代码:

template<class T>
int BST<T>::rank(T x)
{
	return rank(x, root);
}
template<class T>
int BST<T>::rank(T x, Node<T>* t)
{
	if (t == NULL)
		return 0;
	if (x < t->data)
		return rank(x, t->lson);
	else if (x > t->data)
		return 1 + size(t->lson) + rank(x, t->rson);
	else
		return size(t->lson);
}

以下是测试函数:

int main()
{
	BST<int> binaryTree;
	binaryTree.insert(5);
	binaryTree.insert(4);
	binaryTree.insert(2);
	binaryTree.insert(1);
	binaryTree.insert(3);
	binaryTree.insert(7);
	binaryTree.insert(6);
	binaryTree.insert(8);
	bool b = binaryTree.contains(2);
	int x = binaryTree.findMin();
	std::cout <<"是否包含2" <<(b?":是":":否") << " " <<"最小值是:" <<x << std::endl;
	x = binaryTree.findMax();
	std::cout <<"最大值是:" <<x << std::endl;
	std::cout << "删除之前的前序遍历:" << std::endl;
	binaryTree.printTree(ORDER_MODE_PREV);
	std::cout << std::endl;
	binaryTree.Delete(2);
	std::cout << "删除之后前序遍历:" << std::endl;
	binaryTree.printTree(ORDER_MODE_PREV);
	std::cout << std::endl;
	std::cout << "删除之后中序遍历:" << std::endl;
	binaryTree.printTree(ORDER_MODE_MID);
	std::cout << std::endl;
	std::cout << "删除之后后序遍历:" << std::endl;
	binaryTree.printTree(ORDER_MODE_POST);
	std::cout << std::endl;
	x = binaryTree.size();
	std::cout <<"目前树的大小是:"<< x << std::endl;
	x = binaryTree.rank(6);	
	std::cout <<"小于6的元素有:" <<x<<"个";
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值