データ構造avlTree C++実装

9546 ワード

#include <iostream>
using namespace std;
template<class Comparable>
class AvlTree
{
public:
    AvlTree();
    AvlTree(const AvlTree& rhs);
    ~AvlTree();

public:
    const Comparable& findMin() const;   //find the minimum value
    const Comparable& findMax() const;   //find the maximum value
    bool contains(const Comparable& x) const; //Determine whether the tree contains x
    bool isEmpty() const;             //Determine whether the tree is empty
    void printTree() const;           //print the binary Tree
    int size() const;                 //return the tree's size

    void makeEmpty();                 //make Avl tree empty
    void insert(const Comparable& x); //insert a value into Avl tree
    void remove(const Comparable& x); //remove a value from Avl tree

    const AvlTree& operator= (const AvlTree& rhs); //overload operator =
private:
    struct AvlNode
    {
        Comparable element;
        AvlNode* left;
        AvlNode* right;
        AvlNode* parent;
        AvlNode() {}
        AvlNode(const Comparable& theElem, AvlNode* lt, AvlNode* rt, AvlNode* pt, int ht = 0) : element(theElem), left(lt),
                                                                            right(rt), parent(pt), height(ht){}
        int height;
    };
    AvlNode* root; //define the root node
    void insert(const Comparable& x, AvlNode *&t, AvlNode *parent = NULL) const;
    void remove(const Comparable& x, AvlNode *&t);
    AvlNode* findMin(AvlNode* t) const;
    AvlNode* findMax(AvlNode* t) const;
    bool contains(const Comparable& x, AvlNode* t) const;
    void printTree(AvlNode* t) const;
    void makeEmpty(AvlNode *&t) const;
    AvlNode* clone(AvlNode *t) const;
    int height(AvlNode *t) const;
    void rotateWithLeftChild(AvlNode *&k2); //LL   
    void doubleWithLeftChild(AvlNode *&k3); //LR   
    void rotateWithRightChild(AvlNode *&k2); //RR   
    void doubleWithRightChild(AvlNode *&k3); //RL   
    int length;
};
template<class Comparable>
AvlTree<Comparable>::AvlTree() : length(0)
{
    root = new AvlNode(); //constructor construct a tree without subtree
    root = NULL;
}
template<class Comparable>
AvlTree<Comparable>::AvlTree(const AvlTree& rhs)
{
    root = new AvlNode();
    root = NULL;
    makeEmpty();
    root = clone(rhs.root);
    length = rhs.length;
}
template<class Comparable>
AvlTree<Comparable>::~AvlTree()
{
    makeEmpty();
}
template<class Comparable>
const Comparable& AvlTree<Comparable>::findMin() const
{
    return findMin(root)->element;
}
template<class Comparable>
const Comparable& AvlTree<Comparable>::findMax() const
{
    return findMax(root)->element;
}
template<class Comparable>
int AvlTree<Comparable>::size() const
{
    return length;
}
template<class Comparable>
bool AvlTree<Comparable>::contains(const Comparable& x) const
{
    return contains(x, root);
}
template<class Comparable>
bool AvlTree<Comparable>::isEmpty() const
{
    return root == NULL;
}
template<class Comparable>
void AvlTree<Comparable>::printTree() const
{
    printTree(root);
}
template<class Comparable>
void AvlTree<Comparable>::makeEmpty()
{
    makeEmpty(root);
    length = 0;
}
template<class Comparable>
void AvlTree<Comparable>::insert(const Comparable& x)
{
    insert(x, root);
    ++length;
}
template<class Comparable>
void AvlTree<Comparable>::remove(const Comparable& x)
{
    remove(x, root);
    --length;
}
template<class Comparable>
const AvlTree<Comparable>& AvlTree<Comparable>::operator= (const AvlTree& rhs)
{
    if(this != &rhs)
    {
        makeEmpty();
        root = clone(rhs.root);
        length = rhs.length;
    }
    return *this;
}
template<class Comparable>
void AvlTree<Comparable>::insert(const Comparable& x, AvlNode *&t, AvlNode *parent = NULL) const
{
    if(t == NULL)
        t = new AvlNode(x, NULL, NULL, parent);
    else if(x < t -> element)
    {
        insert(x, t -> left, t);
        if(height(t -> left) - height(t -> right) == 2)
        {
          if(x < t -> left -> element)
                 rotateWithLeftChild(t);
             else
                 doubleWithLeftChild(t);
        }
    }
    else if(t -> element < x)
    {
        insert(x, t -> right, t);
        if(height(t -> right) - height(t -> left) == 2)
        {
          if(x < t -> right -> element)
                doubleWithRightChild(t);
            else
                rotateWithRightChild(t);
        }
    }
    else
        ;        //do nothing
        t -> height = max(height(t -> left), height(t -> right)) + 1;
}
template<class Comparable>
void AvlTree<Comparable>::remove(const Comparable& x, AvlNode *&t)
{
    if (t == NULL)
        return;
    if(x < t -> element)
    {
        remove(x, t -> left);
        if(t != NULL)
            t -> height = max(height(t -> left), height(t -> right)) + 1;
        if(height(t -> right) - height(t -> left) == 2)
        {
            if(t -> right -> right -> height > t -> right -> left -> height)
            {
                rotateWithRightChild(t);
            }
            else
            {
                doubleWithRightChild(t);
            }
        }
    }
    else if(t -> element < x)
    {
        remove(x, t -> right);
        if(t != NULL)
        t -> height = max(height(t -> right), height(t -> left)) + 1;
        if(height(t -> left) - height(t -> right) == 2)
        {
            if(t -> left -> left -> height > t -> left -> right -> height)
            {
                rotateWithLeftChild(t);
            }
            else
{
                doubleWithLeftChild(t);
            }
        }
    }
    else if(t -> left != NULL && t -> right != NULL)
    {
        t -> element = findMin(t -> right) -> element;
        remove(t->element, t->right);
    }
    else
    {
        AvlNode *oldNode = t;
        AvlNode *oldParent = t -> parent;
        t = (t -> left != NULL) ? t -> left : t -> right;
        if(t != NULL)
        t -> parent = oldParent;
        delete oldNode;
    }
}
template<class Comparable>
typename AvlTree<Comparable>::AvlNode* AvlTree<Comparable>::findMin(AvlNode *t) const
{
    if(t == NULL)
        return NULL;
    if(t -> left == NULL)
        return t;
    return findMin(t -> left);
}
template<class Comparable>
typename AvlTree<Comparable>::AvlNode* AvlTree<Comparable>::findMax(AvlNode *t) const
{
    if(t == NULL)
        return NULL;
    if(t -> right == NULL)
        return t;
    return findMax(t -> right);
}
template<class Comparable>
bool AvlTree<Comparable>::contains(const Comparable& x, AvlNode* t) const
{
    if(t == NULL)
        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;
}
template<class Comparable>
void AvlTree<Comparable>::makeEmpty(AvlNode*& t) const
{
    if(t != NULL)
    {
        makeEmpty(t -> left);
        makeEmpty(t -> right);
        delete t;
    }
    t = NULL;
}
template<class Comparable>
void AvlTree<Comparable>::printTree(AvlNode* t) const
{
    if(t != NULL)
    {
        cout << t ->element << "\t";
        printTree(t -> left);
        cout << endl;
        printTree(t -> right);
    }
}
template<class Comparable>
typename AvlTree<Comparable>::AvlNode* AvlTree<Comparable>::clone(AvlNode *t) const
{
    if(t == NULL)
        return NULL;
    return new AvlNode(t -> element, clone(t -> left), clone(t -> right), t -> parent);
}
template<class Comparable>
int AvlTree<Comparable>::height(AvlNode* t) const
{
    return (t == NULL) ? -1 : t -> height;
}
template<class Comparable>
void AvlTree<Comparable>::rotateWithLeftChild(AvlNode *&k2)
{
    AvlNode* k1 = k2 -> left;
    k2 -> left = k1 -> right;
    k1 -> right = k2;
    k1 -> parent = k2 -> parent;
    k2 -> parent = k1;
    k2 -> height = max(height(k2 -> left), height(k2 -> right)) + 1;
    k1 -> height = max(height(k1 -> left), k2 -> height) + 1;
    k2 = k1;
}
template<class Comparable>
void AvlTree<Comparable>::doubleWithLeftChild(AvlNode *&k3)
{
    rotateWithRightChild(k3 -> left);
    rotateWithLeftChild(k3);
}
template<class Comparable>
void AvlTree<Comparable>::rotateWithRightChild(AvlNode *&k2)
{
    AvlNode* k1 = k2 -> right;
    k2 -> right = k1 -> left;
    k1 -> left = k2;
    k1 -> parent = k2 -> parent;
    k2 -> parent = k1;
    k2 -> height = max(height(k2 -> left), height(k2 -> right)) + 1;
    k1 -> height = max(height(k1 -> right), k2 -> height) + 1;
    k2 = k1;
}
template<class Comparable>
void AvlTree<Comparable>::doubleWithRightChild(AvlNode *&k3)
{
    rotateWithLeftChild(k3 -> right);
    rotateWithRightChild(k3);
}
int main()
{
    return 0;
}