二叉搜索树的一些实现

二叉搜索树的实现,以及总要想的函数传参和返回值......

一个关于返回值引用的链接:

http://blog.csdn.net/keyouan2008/article/details/5741917


//二叉排序树,每个结点的左子树都比这个结点小,右子树比这个结点大
//构造,析构,找最大,最小,插入,删除,找树中是否含有某一个结点
template <typename Comparable>
class BinarySearchTree
{
public:              //用public的函数调用private的函数,有的如果发现公有的函数没有实现,那么缺的就是一个它调用私有函数的过程,比如makeEmpty()没有写,但是就调用的是私有函数的void makeEmpty(BinaryNode* & t);
	/*
	返回指向函数调用前就已经存在的对象的引用是正确的。当不希望返回的对象被修改时,返回const引用是正确的。
	关于返回的类型:
	1)主函数main的返回值:这里提及一点,返回0表示程序运行成功。

	2)返回非引用类型:函数的返回值用于初始化在跳用函数出创建的临时对象。用函数返回值初始化临时对象与用实参初始化形参的方法是一样 的。如果返回类型不是引用,在调用函数的地方会将函数返回值复制给临时对象。且其返回值既可以是局部对象,也可以是求解表达式的结果。

	3)返回引用:当函数返回引用类型时,没有复制返回值。相反,返回的是对象本身。
	*/
	BinarySearchTree(); //构造函数
	BinarySearchTree(const BinarySearchTree &rhs); //拷贝构造函数
	~BinarySearchTree(); //析构函数

	const Comparable & findMax() const;
	const Comparable & findMin() const;
	bool contains(const Comparable &x) const;    //查找树里有没有x这个数的结点
	bool isEmpty() const;
	void printTree() const;

	void makeEmpty();    //析构用的
	void insert(const Comparable &x);
	void remove(const Comparable &x);
	const BinarySearchTree & operator=(const BinarySearchTree & rhs);     //运算符重载

private:
	struct BinaryNode     //树里的每个结点
	{
		Comparable element;
		BinaryNode *left;      //二叉树左右子树
		BinaryNode *right;

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

	};
	BinaryNode *root;
	//t代表的是子树的根,比如下面的insert就是把x插入到以t为根结点的子树里
	void insert(const Comparable &x, BinaryNode* & t)const;           //不知道对不对......原来的树的结点不能变,所以后面的const有,但是插入之后树变了,所以返回值不能是const,所以前面的const没有
	void remove(const Comparable &x, BinaryNode* & t)const;
	BinaryNode* findMin(BinaryNode *t) const;                       //找以这个为根的子树的最大的结点
	BinaryNode* findMax(BinaryNode *t) const;
	/*自己的关于传入参数的理解:
	传进去新的就用&,传入引用,但是如果是一开始就有的,不是新的,就不用&了,
	所以上面是BinaryNode* & t,下面就是BinaryNode* t。
	觉得传值,如果涉及到改动(就是说,要改动传进来的参数,数值,位置之类的),
	就是类似于,a和b交换的那种问题(改动传进来的参数的数值),
	还有上面的要把结点插进去(改动传进来的参数的位置),
	能用引用用引用,因为引用只是起别的名字,这样子不会产生新的内存。
	但是下面的,只是根据传进来的参数找东西,而不是要改动些东西,就不用&了
	*/

	bool contains(const Comparable & x, BinaryNode * t) const;       //const Comparable & x,呃,这种类型的,就记住吧,见得比较多...大家都这么用...
	void makeEmpty(BinaryNode* & t);  //上面的析构调用这个析构来搞
	void printTree(BinaryNode *t) const;
	BinaryNode* clone(BinaryNode *t)const;


	//具体的函数内容
	bool contains(const Comparable &x) const
	{
		return contains(x, root);
	}

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


	void insert(const Comparable &x)
	{
		insert(x, root);
	}

	void insert(const Comparable &x, BinaryNode* & t)const
	{
		if (t == NULL)
		{
			t = new BinaryNode(x, NULL,NULL);
		}
		else
		{
			if (x < t->element)
			{
				insert(x, t->left);
			}
			else if (x > t->element)
			{
				insert(x, t->right);
			}
		}
	}

	
	BinaryNode* findMax(BinaryNode *t) const
	{
		if (t == NULL)
			return NULL;
		else if (t->right == NULL)
			return t;
		else
			return findMax(t->right);
	}

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


	void remove(const Comparable &x);

	void remove(const Comparable &x, BinaryNode* & t)const;
	{
		if (t == NULL)
			return;
		if (x < t->element)
			remove(x, t->left);
		else if (x>t->element)
			remove(x, t->right);
		else if (t->left != NULL&&t->right != NULL)
		{
			t->element = findMin(t->right)->element;
			remove(t->element, t->right);
		}
		else          //这里注意,删除结点,先用一个指针指向这个结点,然后把新结点弄过来,再删除老的结点
		{
			BinaryNode *oldNode = t;
			t = (t->left != NULL) ? t->left : t->right;
			delete oldNode;
		}
	}

	~BinaryNode()
	{
		makeEmpty();
	}

	void makeEmpty(BinaryNode* & t)
	{
		if (t != NULL)
		{
			remove(t->left);
			remove(t->right);
			delete t;
		}
		t = NULL;               //把t的指针指向空
	}


	/**
	*深拷贝
	*/
	const BinarySearchTree & operator=(const BinarySearchTree &rhs)
	{
		if (this != &rhs)
		{
			makeEmpty();
			root = clone(rhs.root);         //深拷贝不是让两个指向一个空间,就是两个指针指向一棵树,而是弄出来两棵树
		}
		return *this;
	}

	BinaryNode * clone(BinaryNode *t) const
	{
		if (t == NULL)
			return NULL;
		return new BinaryNode(t->element, clone(t->left), clone(t->right));
	}

	//中序遍历,打印一棵树
	void printTree(ostream & out = cout) const
	{
		if (isEmpty())
			out << "Empty tree" << endl;
		else
			printTree(root, out);
	}

	void printTree(BinaryNode *t, ostream & out) const
	{
		if (t != NULL)
		{
			printTree(t->left, out);
			out << t->element << endl;
			printTree(t->right, out);
		}
	}

	//后序遍历,求树的高度
	int height(BinaryNode *t)
	{
		if (t == NULL)
			return -1;
		else
			return 1 + max(height(t->left), height(t->right));
	}
	//还有一种遍历,叫做层序遍历,就是深度为d的结点要在深度为d+1的结点之前进行处理。这种遍历不用递归实施,用队列来做,而不是递归所用的栈
};



发布了56 篇原创文章 · 获赞 9 · 访问量 6万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章