二叉查找树

来源:互联网 发布:python 3.5 2.7 编辑:程序博客网 时间:2024/05/17 12:19

二叉树

二叉树是一颗每个结点都不能多于两个儿子的树。


结点实现

具有N个结点的每一颗二叉树都需要N+1个NULL链。

//二叉树结点类struct BinaryNode{Comprarable element;//The data in the node;BinaryNode *left;//left childBinaryNode *right;//right child};

表达式树

表达式树的树叶是操作数,如常数或变量名字,而其他的结点为操作符。


表达式:aXb+(c-d/e)Xf
前缀式:+XabX-c/def
中缀式:aXb+c-d/eXf(无意义)
后缀式:abXcde/-fX+

构造一颗表达式树


表达式:(a+b)*(c*(d+e))
后缀式:ab+cde+**

二叉查找树


定义:对于树中的每个结点X,它的左子树中所有项的值小于X中的项,而它的右子树中所有项的值大于X中的项

由于树的递归定义,通常是递归的编写这些操作的例程,因为二叉查找树的平均深度是O(logN),所以我们一般不必担心栈空间被用尽。

二叉查找树类的框架:
template<typename Comparable>class BinarySearchTree{public:BinarySearchTree();BinarySearchTree(const BinarySearchTree &rhs);~BinarySearchTree();const Comparable & findMin() const;const Comparable & findMax() const;bool contains(const Comparable &x) const;bool isEmpty() const;bool printTree() const;void makeEmpty();void insert(const Comparable &x);void remove(const Comparable &x);const BinarySearchTree &operator=(const BinarySearchTree &rhs);private://二叉树结点类struct BinaryNode{Comprarable element;//The data in the node;BinaryNode *left;//left childBinaryNode *right;//right childBinaryNode(const Comparable & theElement, BinaryNode *lt, BinaryNode *rt) :element(theElement), left(lt), right(rt){}};BinaryNode *root;void insert(const Comparable &x, BinaryNode * & r) const;void remove(const Comparable &x, BinaryNode * & r) const;BinaryNode * findMin(BinaryNode *t) const;BinaryNode * findMax(BinaryNode *t) const;bool contatins(const Comparable &x, BinaryNode *t) const;void makeEmpty(BinaryNode * & t);void printTree(BinaryNode * & t) const;BinaryNode * clone(BinaryNode *t) const;};

数据成员是指向树根结点的指针,该指针对空树为NULL。几个private成员函数使用引指调用来传递指针变量的技术,这允许public成员函数将指向树根的指针传递给private递归成员函数,然后递归函数就可以改变根的值,于是root就可以指向其他的结点。

contains成员函数

如果在树T中有项为X的结点,那么contains操作就返回true,否则,返回false。关键:考虑问题要全面!
//containstemplate<typename Comparable>bool BinarySearchTree<Comparable>::contains(const Comparable &x, BinaryNode *t) const{if (t == NULL)return false;else if (x < t->element)return contains(x, t->left);else if (x > t->elemnet)return contains(x, t->right);elsereturn true;}template<typename Comparable>bool BinarySearchTree<Comparable>::contains(const Comparable &x) const{return contains(x, root) const;}

使用函数对象而不是使用Comparable项所需做的微小修改

template <typename Object, typename Comparator=less<Object> >class BinarySearchTree{  public:    // Same methods, with Object replacing Comparable  private:    BinaryNode *root;    Comparator isLessThan;    // Same methods, with Object replacing Comparable    /**     * Internal method to test if an item is in a subtree.     * x is item to search for.     * t is the node that roots the subtree.     */    bool contains( const Object & x, BinaryNode *t ) const    {        if( t == NULL )            return false;        else if( isLessThan( x, t->element ) )            return contains( x, t->left );        else if( isLessThan( t->element, x ) )            return contains( x, t->right );        else            return true;    // Match    }};

findMax & findMin


//findMintemplate<typename Comparable>typename BinarySearchTree<Comparable>::BinaryNode * BinarySearchTree<Comparable>::findMin(BinaryNode *t) const{if (t == NULL)return NULL;if (t->left == NULL)return t;return findMin(t->left);}template<typename Comparable>const Comparable & BinarySearchTree<Comparable>::findMin() const{auto temp = findMin(root);if (temp == NULL){cout << "The Tree is Empty" << end;return Comparable();}elsereturn temp->element;}//findMaxtemplate<typename Comparable><pre code_snippet_id="1687240" snippet_file_name="blog_20160517_5_7322944" name="code" class="cpp">typename BinarySearchTree<Comparable>::BinaryNode * <span style="font-family: Arial, Helvetica, sans-serif;">BinarySearchTree<Comparable>::findMax(BinaryNode *t) const</span>
{if (t == NULL)return NULL;if (t->right == NULL)return t;return findMin(t->right);}template<typename Comparable>const Comparable & BinarySearchTree<Comparable>::findMax() const{auto temp = findMin(root);if (temp == NULL){cout << "The Tree is Empty" << end;return Comparable();}elsereturn temp->element;}


insert


//insert//公开接口函数template<typename Comparable>void BinarySearchTree<Comparable>::insert(const Comparable &x){insert(x, root);}//私有函数接口template<typename Comparable>void BinarySearchTree<Comparable>::insert(const Comparable &x, BinaryNode * & t) const{if (t == NULL)t = new BinarySearchTree(x, NULL, NULL);else if (x < t->element)insert(x, t->left);else if (x > t->element)insert(x, t->right);else;//Duplicate; do nothing;}

remove



//remove//公开接口template<typename Comparable>void BinarySearchTree<Comparable>::remove(const Comparable &x){remove(x, root);}//私有函数template<typename Comparable>void BinarySearchTree<Comparable>::remove(const Comparable &x, BinaryNode * &t) const{if (t == NULL)return;else if (x < t->elemet)remove(x, t->left);else if (x > t->element)remove(x, t->right);else if (t->left != NULL && t->right != NULL)//two childen{t->element = findMin(t->right)->element;remove(t->element, t->right);//转化为消除单结点}else//single child{BinaryNode *oldNode = t;t = (t->left != NULL) ? t->left : t->right;delete oldNode;}}

析构函数


//析构函数template<typename Comparable>BinarySearchTree<Comparable>::~BinarySearchTree(){makeEmpty();}template<typename Comparable>void BinarySearchTree<Comparable>::makeEmpty(){makeEmpty(root);}template<typename Comparable>void BinarySearchTree<Comparable>::makeEmpty(BinaryNode * & t){if (t != NULL){makeEmpty(t->left);makeEmpty(t->right);delete t;}t = NULL;}

深度拷贝

template<typename Comparable>const BinarySearchTree & BinarySearchTree<Comparable>::operator=(const BinarySearchTree & rhs){if (this != &rhs){makeEmpty();root = clone(rhs.root);}return *this;}template<typename Comparable>BinaryNode * BinarySearchTree<Comparable>::clone(BinarySearchTree *t) const{if (t == NULL)return NULL;return new BinaryNode(t->element, clone(t->left), clone(t->right));}

源代码:

#ifndef BINARY_SEARCH_TREE_H#define BINARY_SEARCH_TREE_H#include<algorithm>using namespace std;class UnderflowException { };template<typename Comparable>class BinarySearchTree{public:BinarySearchTree() :root(nullptr){};BinarySearchTree(const BinarySearchTree & rhs) :root(nullptr){ root = clone(rhs.root); };BinarySearchTree(BinarySearchTree && rhs) :root(rhs.root){ rhs.root = nullptr; }~BinarySearchTree();const Comparable & findMin() const;const Comparable & findMax() const;bool contains(const Comparable &x) const;bool isEmpty() const;void printTree(ostream & out = cout) const;void makeEmpty();void insert(const Comparable &x);void remove(const Comparable &x);const BinarySearchTree &operator=(const BinarySearchTree & rhs);const BinarySearchTree &operator=(BinarySearchTree && rhs){std::swap(root, rhs.root);return *this;}private://二叉树结点类struct BinaryNode{Comparable element;//The data in the node;BinaryNode *left;//left childBinaryNode *right;//right childBinaryNode(const Comparable & theElement, BinaryNode *lt, BinaryNode *rt) :element(theElement), left(lt), right(rt){}};BinaryNode *root;void insert(const Comparable &x, BinaryNode * & r) const;void remove(const Comparable &x, BinaryNode * & r) const;BinaryNode * findMin(BinaryNode *t) const;BinaryNode * findMax(BinaryNode *t) const;bool contains(const Comparable &x, BinaryNode *t) const;void makeEmpty(BinaryNode * & t);void printTree(BinaryNode * t, ostream &out = cout) const;BinaryNode * clone(BinaryNode *t) const;};/***contains函数,判断该树是否含有某一点**///私有函数template<typename Comparable>bool BinarySearchTree<Comparable>::contains(const Comparable &x, BinaryNode *t) const{if (t == NULL)return false;else if (x < t->element)return contains(x, t->left);else if (x > t->element)return contains(x, t->right);elsereturn true;}//公开接口template<typename Comparable>bool BinarySearchTree<Comparable>::contains(const Comparable &x) const{return contains(x, root);}//findMintemplate<typename Comparable>typename BinarySearchTree<Comparable>::BinaryNode * BinarySearchTree<Comparable>::findMin(BinaryNode *t) const{if (t->left == NULL)return t;return findMin(t->left);}template<typename Comparable>const Comparable & BinarySearchTree<Comparable>::findMin() const{//如果是空,抛出异常if (isEmpty())throw UnderflowException{};return findMin(root)->element;}//findMaxtemplate<typename Comparable>typename BinarySearchTree<Comparable>::BinaryNode * BinarySearchTree<Comparable>::findMax(BinaryNode *t) const{if (t->right == NULL)return t;return findMax(t->right);}template<typename Comparable>const Comparable & BinarySearchTree<Comparable>::findMax() const{//如果是空,抛出异常if (isEmpty())throw UnderflowException{};return findMax(root)->element;}//insert//公开接口函数template<typename Comparable>void BinarySearchTree<Comparable>::insert(const Comparable &x){insert(x, root);}//私有函数接口template<typename Comparable>void BinarySearchTree<Comparable>::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);else;//Duplicate; do nothing;}//remove//公开接口template<typename Comparable>void BinarySearchTree<Comparable>::remove(const Comparable &x){remove(x, root);}//私有函数template<typename Comparable>void BinarySearchTree<Comparable>::remove(const Comparable &x, BinaryNode * &t) const{if (t == NULL)return;else 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)//two childen{t->element = findMin(t->right)->element;remove(t->element, t->right);}else//single child{BinaryNode *oldNode = t;t = (t->left != NULL) ? t->left : t->right;delete oldNode;}}//析构函数template<typename Comparable>BinarySearchTree<Comparable>::~BinarySearchTree(){makeEmpty();}template<typename Comparable>void BinarySearchTree<Comparable>::makeEmpty(){makeEmpty(root);}template<typename Comparable>void BinarySearchTree<Comparable>::makeEmpty(BinaryNode * & t){if (t != NULL){makeEmpty(t->left);makeEmpty(t->right);delete t;}t = NULL;}template<typename Comparable>const BinarySearchTree<Comparable> & BinarySearchTree<Comparable>::operator=(const BinarySearchTree & rhs){/*if (this != &rhs){makeEmpty();root = clone(rhs.root);}*/auto copy = rhs;std::swap(*this, copy);return *this;}template<typename Comparable>typename BinarySearchTree<Comparable>::BinaryNode * BinarySearchTree<Comparable>::clone(BinaryNode *t) const{if (t == NULL)return NULL;return new BinaryNode(t->element, clone(t->left), clone(t->right));}//判断树是否为空template<typename Comparable>bool BinarySearchTree<Comparable>::isEmpty() const{if (root == nullptr)return true;elsereturn false;}//中序遍历template<typename Comparable>void BinarySearchTree<Comparable>::printTree(ostream & out = cout) const{if (isEmpty())out << "Tree is empty" << endl;elseprintTree(root, out);}template<typename Comparable>void BinarySearchTree<Comparable>::printTree(BinaryNode * t, ostream & out = cout) const{if (t != NULL){printTree(t->left, out);out << t->element << "  ";printTree(t->right, out);}}#endif

测试代码:
#include<iostream>#include"BinarySearchTree.h"using namespace std;int main(){BinarySearchTree<int> t;int NUMS = 400000;const int GAP = 3711;int i;cout << "Checking... (no more output means success)" << endl;for (i = 0; i != 100; i++)t.insert(i);t.printTree();for (i = 1; i < 100; i += 2)t.remove(i);cout << endl;t.printTree();cout << "Min = " << t.findMin() << endl;cout << "Max = " << t.findMax() << endl;for (i = 2; i < 100; i += 2)if (!t.contains(i))cout << i <<"Find error1!" << endl;BinarySearchTree<int> t2;t2 = t;t2.printTree();cout << "Finished testing" << endl;system("pause");return 0;}

运行结果:
Checking... (no more output means success)0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  990  2  4  6  8  10  12  14  16  18  20  22  24  26  28  30  32  34  36  38  40  42  44  46  48  50  52  54  56  58  60  62  64  66  68  70  72  74  76  78  80  82  84  86  88  90  92  94  96  98  Min = 0Max = 980  2  4  6  8  10  12  14  16  18  20  22  24  26  28  30  32  34  36  38  40  42  44  46  48  50  52  54  56  58  60  62  64  66  68  70  72  74  76  78  80  82  84  86  88  90  92  94  96  98  Finished testing请按任意键继续. . .

课本源代码:
#ifndef BINARY_SEARCH_TREE_H#define BINARY_SEARCH_TREE_H#include "dsexceptions.h"#include <algorithm>using namespace std;       // BinarySearchTree class//// CONSTRUCTION: zero parameter//// ******************PUBLIC OPERATIONS*********************// void insert( x )       --> Insert x// void remove( x )       --> Remove x// bool contains( x )     --> Return true if x is present// Comparable findMin( )  --> Return smallest item// Comparable findMax( )  --> Return largest item// boolean isEmpty( )     --> Return true if empty; else false// void makeEmpty( )      --> Remove all items// void printTree( )      --> Print tree in sorted order// ******************ERRORS********************************// Throws UnderflowException as warrantedtemplate <typename Comparable>class BinarySearchTree{  public:    BinarySearchTree( ) : root{ nullptr }    {    }    /**     * Copy constructor     */    BinarySearchTree( const BinarySearchTree & rhs ) : root{ nullptr }    {        root = clone( rhs.root );    }    /**     * Move constructor     */    BinarySearchTree( BinarySearchTree && rhs ) : root{ rhs.root }    {        rhs.root = nullptr;    }        /**     * Destructor for the tree     */    ~BinarySearchTree( )    {        makeEmpty( );    }    /**     * Copy assignment     */    BinarySearchTree & operator=( const BinarySearchTree & rhs )    {        BinarySearchTree copy = rhs;        std::swap( *this, copy );        return *this;    }            /**     * Move assignment     */    BinarySearchTree & operator=( BinarySearchTree && rhs )    {        std::swap( root, rhs.root );               return *this;    }            /**     * Find the smallest item in the tree.     * Throw UnderflowException if empty.     */    const Comparable & findMin( ) const    {        if( isEmpty( ) )            throw UnderflowException{ };        return findMin( root )->element;    }    /**     * Find the largest item in the tree.     * Throw UnderflowException if empty.     */    const Comparable & findMax( ) const    {        if( isEmpty( ) )            throw UnderflowException{ };        return findMax( root )->element;    }    /**     * Returns true if x is found in the tree.     */    bool contains( const Comparable & x ) const    {        return contains( x, root );    }    /**     * Test if the tree is logically empty.     * Return true if empty, false otherwise.     */    bool isEmpty( ) const    {        return root == nullptr;    }    /**     * Print the tree contents in sorted order.     */    void printTree( ostream & out = cout ) const    {        if( isEmpty( ) )            out << "Empty tree" << endl;        else            printTree( root, out );    }    /**     * Make the tree logically empty.     */    void makeEmpty( )    {        makeEmpty( root );    }    /**     * Insert x into the tree; duplicates are ignored.     */    void insert( const Comparable & x )    {        insert( x, root );    }         /**     * Insert x into the tree; duplicates are ignored.     */    void insert( Comparable && x )    {        insert( std::move( x ), root );    }        /**     * Remove x from the tree. Nothing is done if x is not found.     */    void remove( const Comparable & x )    {        remove( x, root );    }  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;    /**     * Internal method to insert into a subtree.     * x is the item to insert.     * t is the node that roots the subtree.     * Set the new root of the subtree.     */    void 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( t->element < x )            insert( x, t->right );        else            ;  // Duplicate; do nothing    }        /**     * Internal method to insert into a subtree.     * x is the item to insert.     * t is the node that roots the subtree.     * Set the new root of the subtree.     */    void insert( 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( t->element < x )            insert( std::move( x ), t->right );        else            ;  // Duplicate; do nothing    }    /**     * Internal method to remove from a subtree.     * x is the item to remove.     * t is the node that roots the subtree.     * Set the new root of the subtree.     */    void remove( const Comparable & x, BinaryNode * & t )    {        if( t == nullptr )            return;   // Item not found; do nothing        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 ) // Two children        {            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;        }    }    /**     * Internal method to find the smallest item in a subtree t.     * Return node containing the smallest item.     */    BinaryNode * findMin( BinaryNode *t ) const    {        if( t == nullptr )            return nullptr;        if( t->left == nullptr )            return t;        return findMin( t->left );    }    /**     * Internal method to find the largest item in a subtree t.     * Return node containing the largest item.     */    BinaryNode * findMax( BinaryNode *t ) const    {        if( t != nullptr )            while( t->right != nullptr )                t = t->right;        return t;    }    /**     * Internal method to test if an item is in a subtree.     * x is item to search for.     * t is the node that roots the subtree.     */    bool contains( const Comparable & x, BinaryNode *t ) const    {        if( t == nullptr )            return false;        else if( x < t->element )            return contains( x, t->left );        else if( t->element < x )            return contains( x, t->right );        else            return true;    // Match    }/****** NONRECURSIVE VERSION*************************    bool contains( const Comparable & x, BinaryNode *t ) const    {        while( t != nullptr )            if( x < t->element )                t = t->left;            else if( t->element < x )                t = t->right;            else                return true;    // Match        return false;   // No match    }*****************************************************/    /**     * Internal method to make subtree empty.     */    void makeEmpty( BinaryNode * & t )    {        if( t != nullptr )        {            makeEmpty( t->left );            makeEmpty( t->right );            delete t;        }        t = nullptr;    }    /**     * Internal method to print a subtree rooted at t in sorted order.     */    void printTree( BinaryNode *t, ostream & out ) const    {        if( t != nullptr )        {            printTree( t->left, out );            out << t->element << endl;            printTree( t->right, out );        }    }    /**     * Internal method to clone subtree.     */    BinaryNode * clone( BinaryNode *t ) const    {        if( t == nullptr )            return nullptr;        else            return new BinaryNode{ t->element, clone( t->left ), clone( t->right ) };    }};#endif



0 0
原创粉丝点击