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

来源:互联网 发布:知乎最好用的版本 编辑:程序博客网 时间:2024/05/22 04:53


查找二叉树的实现,参考第四版教材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;elseprintTree(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;elsereturn 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);elsereturn 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;}


阅读全文
0 0
原创粉丝点击