二叉搜索树的实现,以及总要想的函数传参和返回值......
一个关于返回值引用的链接:
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的结点之前进行处理。这种遍历不用递归实施,用队列来做,而不是递归所用的栈 };