Data Structures (Weiss) Chapter 12: Splay Tree 伸展树


//

//  main.cpp

//  Data Structure TRY1

//

//  Created by zr9558 on 6/7/13.

//  Copyright (c) 2013 zr9558. All rights reserved.

//



// Data Structures C++ Weiss: P.521 SplayTree


#include<iostream>

using namespace std;

#include<vector>

#include<math.h>


template<typename Comparable>

class SplayTree

{

public:

    SplayTree()

    {

        nullNode= new BinaryNode;

        nullNode->left=nullNode->right=nullNode;

        root=nullNode;

    }


    SplayTree( const SplayTree &rhs)

    {

        nullNode= new BinaryNode;

        nullNode->left=nullNode->right=nullNode;

        root=clone(rhs.root);

    }

    

    const SplayTree & operator=( const SplayTree &rhs)

    {

        if( this!=&rhs)

        {

            makeEmpty();

            nullNode= new BinaryNode;

            nullNode->left=nullNode->right=nullNode;

            root=clone(rhs.root);

        }

        return *this;

    }

    

    ~SplayTree()

    {

        makeEmpty();

        delete nullNode;

    }

    

    /**

     * Find the largest item in the tree.

     * Not the most efficient implementation (uses two passes), but has correct

     *     amortized behavior.

     * A good alternative is to first call find with parameter

     *     larger than any item in the tree, then call findMax.

     * Return the largest item or throw UnderflowException if empty.

     */

    const Comparable & findMax() 

    {

        BinaryNode *ptr=root;

        

        while( ptr->right!=nullNode)

            ptr=ptr->right;

        

        splay(ptr->element, root);

        return ptr->element;

        

    }


    /**

     * Find the smallest item in the tree.

     * Not the most efficient implementation (uses two passes), but has correct

     *     amortized behavior.

     * A good alternative is to first call find with parameter

     *     smaller than any item in the tree, then call findMin.

     * Return the smallest item or throw UnderflowException if empty.

     */

    const Comparable & findMin()

    {

        BinaryNode *ptr=root;

        

        while( ptr->left!=nullNode)

            ptr=ptr->left;

        

        splay(ptr->element,root);

        return ptr->element;

    }

    

    bool contains( const Comparable &x) const

    {

        return contains(x,root);

    }

    

    bool isEmpty() const

    {

        return root==nullNode;

    }

    

    void printTree() const

    {

        printtree(root);

    }

    

    void printTree1() const

    {

        printtree1(root,0);

    }

    

    void makeEmpty()

    {

        /******************************

         * Comment this out, because it is prone to excessive

         * recursion on degenerate trees. Use alternate algorithm.

         

         reclaimMemory( root );

         root = nullNode;

         *******************************/

        

        while( !isEmpty())

        {

            findMax(); // Splay max item to root

            remove(root->element);

        }

        

    }

    

    void insert( const Comparable &x);

    void remove( const Comparable &x);

    

private:

    struct BinaryNode

    {

        Comparable element;

        BinaryNode *left, *right;

        

        BinaryNode():left(NULL), right(NULL){}

        BinaryNode( const Comparable &theElement, BinaryNode *lt, BinaryNode *rt)

        : element(theElement), left(lt), right(rt){}

        

    };

    

    BinaryNode *root;

    BinaryNode *nullNode;

    

    void rotateWithLeftChild( BinaryNode *&k2)

    {

        BinaryNode *k1=k2->left;

        k2->left=k1->right;

        k1->right=k2;

        k2=k1;

    }

    

    void rotateWithRightChild( BinaryNode *&k2)

    {

        BinaryNode *k1=k2->right;

        k2->right=k1->left;

        k1->left=k2;

        k2=k1;

    }

    

    void splay( const Comparable &x, BinaryNode * &t)

    {

        BinaryNode *leftTreeMax, *rightTreeMin;

        static BinaryNode header;

        

        header.left=header.right=nullNode;

        leftTreeMax=rightTreeMin=&header;

        

        nullNode->element=x; // Guarantee a match

        

        for( ; ; )

        {

            if( x<t->element)

            {

                if( x<t->left->element)

                    rotateWithLeftChild(t);

                if( t->left==nullNode)

                    break;

                

                // Link Right

                rightTreeMin->left=t;

                rightTreeMin=t;

                t=t->left;

            }

            else if( x>t->element)

            {

                if( x>t->right->element)

                    rotateWithRightChild(t);

                if( t->right==nullNode)

                    break;

                

                // Link Left

                leftTreeMax->right=t;

                leftTreeMax=t;

                t=t->right;

            }

            else break;

        }

        

        leftTreeMax->right=t->left;

        rightTreeMin->left=t->right;

        t->left=header.right;

        t->right=header.left;

        

    }

    

    BinaryNode *clone( BinaryNode *t)

    {

        if( t==t->left) return nullNode; // Cannot test against nullNode;

        

        return new BinaryNode(t->element, clone(t->left), clone(t->right));

    }

    

    bool contains( const Comparable &x, BinaryNode *t) const

    {

        if( t==t->left) 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;

    }

    

    void printtree( BinaryNode *t) const

    {

        if( t!=nullNode

        {

            printtree(t->left);

            cout<<t->element<<endl;

            printtree(t->right);

        }

    }

    

    void printtree1( BinaryNode *t, int level) const

    {

        if(t!=nullNode)

        {

            printtree1( t->right, level+1);

            

            for( int i=0; i<4*level; ++i)

                cout<<" ";

            cout<<t->element<<endl;

            

            printtree1( t->left, level+1);

        }

    }

    

};


template<typename Comparable>

void SplayTree<Comparable>::insert( const Comparable &x)

{

    static BinaryNode *newNode=NULL;

    

    if( newNode==NULL)

        newNode=new BinaryNode;

    

    newNode->element=x;

    

    if( root==nullNode)

    {

        newNode->left=newNode->right=nullNode;

        root=newNode;

    }

    else

    {

        splay(x,root);

        if( x<root->element)

        {

            newNode->left=root->left;

            newNode->right=root;

            root->left=nullNode;

            root=newNode;

        }

        else if( x>root->element)

        {

            newNode->right=root->right;

            newNode->left=root;

            root->right=nullNode;

            root=newNode;

        }

        else return;

    }

    newNode=NULL; // so next insert will call new, since newNode is a static variable.

}


template<typename Comparable>

void SplayTree<Comparable>::remove(const Comparable &x)

{

    BinaryNode *newTree;

    

    // If x is found, it will be at the root

    splay(x,root);

    if( root->element!=x)

        return; // Item not found, do nothing

    

    if( root->left==nullNode)

        newTree=root->right;

    else

    {

        //Find the maximum in the left subtree

        // Splay it to the root; and then attach right child

        

        newTree=root->left;

        splay(x,newTree);

        newTree->right=root->right;

    }

    

    delete root;

    root=newTree;

    

}




int main()

{

    SplayTree<int> T1;

    

    for( int i=0; i<30; ++i)

        T1.insert(rand()%100);

    

    SplayTree<int> T=T1;

    

    T.printTree1();

    T.printTree();

    

    int x;

    while( cin>>x)

    {

        if( T.contains(x)) { T.remove(x); T.printTree1();}

        else cout<<"no contain"<<endl;

    }

    

    


    

    

    return 0;

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值