数据结构与算法分析 c++11 查找二叉树 BinarySearchTree


查找二叉树的实现,参考第四版教材P109页。

  需要注意的是,对于含n个结点的二叉树,树的平均高度为h=「log(n+1)|。 但是如果给定的是有序的递增递减的数,那么树的高度就为n, 即只存在左子树或右子树,所以为了降低树的高度,减小搜索复杂度,最好给定无序的数值。

binarySearchTree.h  文件:

#pragma once
#include <ostream>
template <typename Comparable>
class BinarySearchTree
{
public:
	BinarySearchTree():root(nullptr){};
	BinarySearchTree(const BinarySearchTree & rhs) : root(nullptr)
	{
		root = clone(rhs.root);
	}
	BinarySearchTree(BinarySearchTree && rhs) : root(nullptr)
	{
		root = clone(std::move(rhs.root))
	}

	~BinarySearchTree() { makeEmpty(); }

	const Comparable & findMin() const { return findMin(root)->element; }
	const Comparable & findMax() const { return  findMax(root)->element; }
	bool contains(const Comparable & x)const { return contains(x, root); }       /* 如果在树中找到x, 返回true.*/
	bool isEmpty() const { return root == nullptr; };
	void printTree(std::ostream  & out = cout)const
	{
		if (isEmpty())
			out << "Empty tree" << endl;
		else
			printTree(root, out);
	}

	void makeEmpty()   { makeEmpty(root); }
	void insert(const Comparable & x)   { insert(x, root); }           /*将x插入树中,忽略重复元*/
	void insert(Comparable ** x)    { insert(std::move(x), root); }
	void remove(const Comparable & x)  { remove(x, root); };

	BinarySearchTree & operator = (const BinarySearchTree & rhs)
	{
		if (this != &rhs)
		{
			BinaryNode *tmp = clone(rhs.root);
			makeEmpty();
			root = tmp;
		}
		return *this;
	}

	BinarySearchTree & operator =(BinarySearchTree && rhs)
	{
		if (this != std::move(rhs))
		{
			BinaryNode *tmp = clone(std::move(rhs.root));
			makeEmpty();
			root = tmp;
		}
		return *this;
	}

private:
	struct BinaryNode {
		Comparable element;
		BinaryNode *left;
		BinaryNode *right;

		BinaryNode(const Comparable & theElement, BinaryNode *lt, BinaryNode *rt)
			: element(theElement),left(lt),right(rt) { }
		BinaryNode (Comparable && theElement, BinaryNode *lt ,BinaryNode *rt)
			: element(std::move(theElement)),left(lt),right(rt) { }
	};

	BinaryNode *root;

	void insert(const Comparable & x, BinaryNode * & t);
	void insert(const Comparable &&x, BinaryNode * & t);
	void remove(const Comparable & x, BinaryNode * & t);

	BinaryNode * findMin(BinaryNode *t) const
	{
		if (t == nullptr)
			return nullptr;
		if (t->left == nullptr)
			return t;
		return findMin(t->left);
	}

	BinaryNode * findMax(BinaryNode *t) const
	{
		if (t != nullptr)
			while (t->right != nullptr)
				t = t->right;
		return t;
	}

	bool contains(const Comparable & x, BinaryNode *t)const;
	void makeEmpty(BinaryNode * &t);
	void printTree(BinaryNode *t, std::ostream & out)const;
	BinaryNode * clone(BinaryNode *t)const
	{
		if (t == nullptr)
			return nullptr;
		else
			return new BinaryNode(t->element, clone(t->left), clone(t->right));
	}

};



/*
* 向子树插入元素的内部方法。
* x 是要插入的项。
* t 为该子树的根节点。
* 置子树的新根。
*/
template<typename Comparable>
inline void BinarySearchTree<Comparable>::insert(const Comparable & x, BinaryNode *& t)
{
	if (t == nullptr)
		t = new BinaryNode(x, nullptr, nullptr);
	else if (x < t->element)
		insert(x, t->left);
	else if (x > t->element)
		insert(x, t->right);
	else
		;  // 重复元什么也不做
}

template<typename Comparable>
inline void BinarySearchTree<Comparable>::insert(const Comparable && x, BinaryNode *& t)
{
	if (t == nullptr)
		t = new BinaryNode(std::move(x), nullptr, nullptr);
	else if (x < t->element)
		insert(std::move(x), t->left);
	else if (x > t->element)
		insert(std::move(x), t->right);
	else
		;  //重复元,什么也不做
}

/*
* 使子树为空的内部方法。
*/
template<typename Comparable>
inline void BinarySearchTree<Comparable>::makeEmpty(BinaryNode * &t)
{
	if (t != nullptr)
	{
		makeEmpty(t->left);
		makeEmpty(t->right);
		delete t;
	}
	t = nullptr;
}


/*
* 从一棵树删除一项的内部方法。
* x 是要被删除的项。
* t 为该子树的根节点。
* 置该子树的新根。
*/
template<typename Comparable>
void BinarySearchTree<Comparable>::remove(const Comparable & x, BinaryNode *& t)
{
	if (t == nullptr)
		return;  //没找到,什么也不做
	if (x < t->element)
		remove(x, t->left);
	else if (t->element < x)
		remove(x, t->right);
	else if (t->left != nullptr && t->right != nullptr) //有两个儿子
	{
		t->element = findMin(t->right)->element;
		remove(t->element, t->right);
	}
	else {
		BinaryNode *oldNode = t;
		t = (t->left != nullptr) ? t->left : t->right;
		delete oldNode;
	}
}


/*
以排序的顺序打印根在t处的子树的内部方法。
*/
template<typename Comparable>
inline void BinarySearchTree<Comparable>::printTree(BinaryNode * t, std::ostream & out) const
{
	if (t != nullptr)
	{
		printTree(t->left, out);
		out << t->element << endl;
		printTree(t->right, out);
	}
}


/*
*  测试一项是否在子树上的内部方法。
*  x 是要查找的项。
*  t 是作为该子树的根的节点。
*/
template<typename Comparable>

inline bool BinarySearchTree<Comparable>::contains(const Comparable & x, BinaryNode * t) const
{
	if (t == nullptr)
		return false;
	else if (x < t->element)
		return contains(x, t->left);
	else if (x> t->element)
		return contains(x, t->right);
	else
		return true;
}



main.c   测试主程序:

#include <iostream>
#include <vector>
#include "binarySearchTree.h"

using namespace std;


int main()
{

    vector<int> num = { 6,2,8,1,4,3,5 };
	BinarySearchTree<int> bst;
	/*生成二叉查找树*/
//	for(auto & note: num)
//	   bst.insert(note);

	int x;
	cout << "请输入数字:"<< endl;
	while (cin >> x && x)//以0作为输入结束   
	{
		bst.insert(x);
	}

	cout << "   打印二叉树:   " << endl;
	bst.printTree();

	cout << "删除小于5的数:" << endl;
	for (size_t i=0; i < 5; ++i)
		bst.remove(i);
	cout << "删除后的二叉树:" << endl;
	bst.printTree();

	cout <<" 测试查找contains()函数:" << endl;
	cout << bst.contains(7) << endl;

	cout << "测试最大最小值:" << endl;
	cout << "最大值: " << bst.findMax() << endl;
	cout << "最小值: " << bst.findMin() << endl;

	cout << "测试拷贝构造函数: " << endl;
	BinarySearchTree<int> bst2(bst);
	bst2.printTree();

	cout << "测试赋值操作: " << endl;
	BinarySearchTree<int> bst3;
	bst3 = bst2;
	bst3.printTree();
	cout <<"所有测试完成!"<< endl;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值