= =AVL树和伸展树的代码实现

//ConstVar.h常数定义
#ifndef MYOOP_CONSTVAR_H
#define MYOOP_CONSTVAR_H
const int PREORDER = 1;
const int INORDER = 2;
const int POSTORDER = 3;
#endif //MYOOP_CONSTVAR_H

//AVL树

#ifndef MYOOP_AVLTREE_H
#define MYOOP_AVLTREE_H

#include <iostream>
#include "ConstVar.h"
#include <algorithm>
using std::max;

template <class T>
class AVLNode{
public:
    T element;
    int height;
    AVLNode* parent;
    AVLNode* left;
    AVLNode* right;
    AVLNode(const T& element,AVLNode* parent ){
        height = 0;
        this->element = element;
        this->parent = parent;
        left = right = nullptr;
    }
};

template <class T>
class AVLTree{
private:
    AVLNode<T> * root;
public:
    AVLTree();
    ~AVLTree();
    AVLTree(const AVLTree & tree);
    AVLNode<T>* getRoot();
    AVLNode<T>* find(const T& value);
    void insert(const T& value);
    void remove(const T& value);
    void printTree(const int & code);
    void makeEmpty();
private:
    int Height(const AVLNode<T>* tree) const ;
    void leftRotation(AVLNode<T>* aboveNode);
    void rightRotation(AVLNode<T>* aboveNode);
    AVLNode<T> *findMin(AVLNode<T>* tree) const ;
    void insert(const T& value, AVLNode<T>* parent);
    void remove(const T &value,AVLNode<T>* &tree);
    void replace(AVLNode<T>* ori,AVLNode<T>* to);
    void inorder(const AVLNode<T>* tree) const ;
    void preorder(const AVLNode<T>* tree) const ;
    void postorder(const AVLNode<T>* tree) const ;
    void makeEmpty(AVLNode<T>* &tree);
};

template <class T>
AVLTree<T>::AVLTree() {
    root = nullptr;
}
template <class T>
AVLTree<T>::~AVLTree() {
    makeEmpty();
}
template <class T>
AVLTree<T>::AVLTree(const AVLTree<T> &tree) {
    this->root = tree.root;
}
template <class T>
AVLNode<T>* AVLTree<T>::getRoot() {
    return root;
}
template <class T>
AVLNode<T>* AVLTree<T>::find(const T &value) {
    if(!this->root) return nullptr;
    AVLNode<T>* cur = this->root;
    while(cur != nullptr){
        if(cur->element == value) return cur;
        else if(value<cur->element){
            cur = cur->left;
        }else{
            cur = cur->right;
        }
    }
    return nullptr;
}
template <class T>
int AVLTree<T>::Height(const AVLNode<T>* tree)const {
    if(!tree) return -1;
    else return tree->height;
}
template <class T>
void AVLTree<T>::leftRotation(AVLNode<T> *aboveNode) {
    AVLNode<T>* child = aboveNode->right;
    if(child){
        aboveNode->right = child->left;
        if(child->left) child->left->parent = aboveNode;
        child->parent = aboveNode->parent;
        child->left = aboveNode;
    }
    if(!aboveNode->parent){
        root = child;
    }else if(aboveNode==aboveNode->parent->left)
        aboveNode->parent->left = child;
    else
        aboveNode->parent->right = child;
    aboveNode->parent = child;

    aboveNode->height = max(Height(aboveNode->left),Height(aboveNode->right))+1;
    if(child) child->height = max(Height(child->left),Height(child->right))+1;
}
template <class T>
void AVLTree<T>::rightRotation(AVLNode<T> *aboveNode) {
    AVLNode<T>* child = aboveNode->left;
    if(child){
        aboveNode->left = child->right;
        if(child->right) child->right->parent = aboveNode;
        child->parent = aboveNode->parent;
        child->right = aboveNode;
    }
    if(!aboveNode->parent){
        root = child;
    }else if(aboveNode==aboveNode->parent->left)
        aboveNode->parent->left = child;
    else
        aboveNode->parent->right = child;
    aboveNode->parent = child;

    aboveNode->height = max(Height(aboveNode->left),Height(aboveNode->right))+1;
    if(child) child->height = max(Height(child->left),Height(child->right))+1;
}
template <class T>
void AVLTree<T>::printTree(const int &code) {
    switch(code){
        case PREORDER:
            preorder(this->root);
            break;
        case INORDER:
            inorder(this->root);
            break;
        case POSTORDER:
            postorder(this->root);
            break;
        default:break;
    }
    std::cout<<std::endl;
}
template <class T>
void AVLTree<T>::preorder(const AVLNode<T> *tree) const {
    if(tree){
        std::cout<<tree->element<<' ';
        preorder(tree->left);
        preorder(tree->right);
    }
}
template <class T>
void AVLTree<T>::inorder(const AVLNode<T> *tree) const {
    if(tree){
        inorder(tree->left);
        std::cout<<tree->element<<' ';
        inorder(tree->right);
    }
}
template <class T>
void AVLTree<T>::postorder(const AVLNode<T> *tree) const {
    if(tree){
        postorder(tree->left);
        postorder(tree->right);
        std::cout<<tree->element<<' ';
    }
}
template <class T>
void AVLTree<T>::makeEmpty() {
    makeEmpty(root);
}
template <class T>
void AVLTree<T>::makeEmpty(AVLNode<T> *&tree) {
    if(!tree) return ;
    if(tree->left) makeEmpty(tree->left);
    if(tree->right) makeEmpty(tree->right);
    delete tree;
    tree = nullptr;
}
template <class T>
AVLNode<T>* AVLTree<T>::findMin(AVLNode<T> *tree) const {
    if(!tree) return nullptr;
    while(tree->left != nullptr) tree = tree->left;
    return tree;
}

template <class T>
void AVLTree<T>::insert(const T &value) {
    if(!root) root = new AVLNode<T>(value, nullptr);
    else insert(value,root);
}

template <class T>
void AVLTree<T>::insert(const T &value, AVLNode<T> *parent) {
    if(value < parent->element){
        if(parent->left){
            insert(value,parent->left);
        }else{
            parent->left = new AVLNode<T>(value,parent);
        }
        parent->height = max(Height(parent->left),Height(parent->right))+1;
        if(Height(parent->left)-Height(parent->right)==2){
            if(value<parent->left->element){
                //ll
                rightRotation(parent);
            }else{
                //lr
                leftRotation(parent->left);
                rightRotation(parent);
            }
        }
    }else if(value > parent->element){
        if(parent->right){
            insert(value,parent->right);
        }else{
            parent->right = new AVLNode<T>(value,parent);
        }
        parent->height = max(Height(parent->left),Height(parent->right))+1;
        if(Height(parent->right)-Height(parent->left)==2){
            if(value>parent->right->element){
                //rr
                leftRotation(parent);
            }else{
                //rl
                rightRotation(parent->right);
                leftRotation(parent);
            }
        }
    }else{
        //do nothing
    }

}
template <class T>
void AVLTree<T>::replace(AVLNode<T> *ori, AVLNode<T> *to) {
    if(ori->parent==nullptr)
        this->root = to;
    else if(ori == ori->parent->left)
        ori->parent->left = to;
    else
        ori->parent->right = to;
    if(to != nullptr) to->parent = ori->parent;
}
template <class T>
void AVLTree<T>::remove(const T &value) {
   remove(value,root);
}
template <class T>
void AVLTree<T>::remove(const T &value,AVLNode<T> *&tree) {
    if(!tree) return ;
    if(value<tree->element){
        remove(value,tree->left);
        if(Height(tree->right)-Height(tree->left)==2){
            if(Height(tree->right->right)>=Height(tree->right->left)){
                leftRotation(tree);
            }else{
                rightRotation(tree->right);
                leftRotation(tree);
            }
        }
    }else if(value>tree->element){
        remove(value,tree->right);
        if(Height(tree->left)-Height(tree->right)==2){
            if(Height(tree->left->left)>=Height(tree->left->right)){
                rightRotation(tree);
            }else{
                leftRotation(tree->left);
                rightRotation(tree);
            }
        }
    }else{
        if(tree->left!=nullptr && tree->right!= nullptr){
            AVLNode<T>* minnode = findMin(tree->right);
            tree->element = minnode->element;
            minnode->element = value;
            remove(value,tree->right);
            tree->height = max(Height(tree->left),Height(tree->right))+1;
        }else if(tree->left == nullptr){
            replace(tree,tree->right);
        }else if(tree->right == nullptr){
            replace(tree,tree->left);
        }
    }
    if(tree) tree->height = max(Height(tree->left),Height(tree->right))+1;
}


#endif //MYOOP_AVLTREE_H

//伸展树
#ifndef MYOOP_SPLAYTREE_H
#define MYOOP_SPLAYTREE_H

#include <iostream>
#include "ConstVar.h"
#include "AVLTree.h"

template <class T>
class SPTNode{
public:
    T element;
    SPTNode* parent;
    SPTNode* left;
    SPTNode* right;
    SPTNode(const T& element,SPTNode* parent ){
        this->element = element;
        this->parent = parent;
        left = right = nullptr;
    }
};

template <class T>
class SPTree{
private:
    SPTNode<T> * root;
public:
    SPTree();
    ~SPTree();
    SPTree(const SPTree & tree);
    SPTNode<T>* getRoot();
    SPTNode<T>* find(const T& value);
    void insert(const T& value);
    void remove(const T& value);
    void printTree(const int & code);
    void makeEmpty();
private:
    void leftRotation(SPTNode<T>* aboveNode);
    void rightRotation(SPTNode<T>* aboveNode);
    void splay(SPTNode<T>* node);
    SPTNode<T> *findMin(SPTNode<T>* tree) const ;
    void insert(const T& value, SPTNode<T>* parent);
    void remove(SPTNode<T>* &target);
    void replace(SPTNode<T>* ori,SPTNode<T>* to);
    void inorder(const SPTNode<T>* tree) const ;
    void preorder(const SPTNode<T>* tree) const ;
    void postorder(const SPTNode<T>* tree) const ;
    void makeEmpty(SPTNode<T>* &tree);
};
template <class T>
SPTree<T>::SPTree() { 
    root = nullptr;
}
template <class T>
SPTree<T>::~SPTree() {
    makeEmpty();
}
template <class T>
SPTree<T>::SPTree(const SPTree & tree) {
    this->root = tree.root;
}
template <class T>
SPTNode<T>* SPTree<T>::getRoot() {
    return this->root;
}
template <class T>
void SPTree<T>::leftRotation(SPTNode<T> *aboveNode) {
    SPTNode<T>* child = aboveNode->right;
    if(child){
        aboveNode->right = child->left;
        if(child->left) child->left->parent = aboveNode;
        child->parent = aboveNode->parent;
        child->left = aboveNode;
    }
    if(!aboveNode->parent){
        root = child;
    }else if(aboveNode==aboveNode->parent->left)
        aboveNode->parent->left = child;
    else
        aboveNode->parent->right = child;
    aboveNode->parent = child;
}
template <class T>
void SPTree<T>::rightRotation(SPTNode<T> *aboveNode) {
    SPTNode<T>* child = aboveNode->left;
    if(child){
        aboveNode->left = child->right;
        if(child->right) child->right->parent = aboveNode;
        child->parent = aboveNode->parent;
        child->right = aboveNode;
    }
    if(!aboveNode->parent){
        root = child;
    }else if(aboveNode==aboveNode->parent->left)
        aboveNode->parent->left = child;
    else
        aboveNode->parent->right = child;
    aboveNode->parent = child;
}
template <class T>
void SPTree<T>::splay(SPTNode<T> *node) {
    if(!node) return ;
    while(node->parent){
        if(!node->parent->parent){
            if(node==node->parent->left){
                rightRotation(node->parent);
            }else{
                leftRotation(node->parent);
            }
        }else{
            if(node==node->parent->left&&node->parent==node->parent->parent->left){
                rightRotation(node->parent->parent);
                rightRotation(node->parent);
            }else if(node==node->parent->right && node->parent==node->parent->parent->right){
                leftRotation(node->parent->parent);
                leftRotation(node->parent);
            }else if(node==node->parent->right && node->parent==node->parent->parent->left){
                leftRotation(node->parent);
                rightRotation(node->parent);
            }else{
                rightRotation(node->parent);
                leftRotation(node->parent);
            }
        }
    }
}
template <class T>
SPTNode<T>* SPTree<T>::find(const T &value) {
    if(!root) return nullptr;
    SPTNode<T>* cur = root;
    while(cur!=nullptr){
        if(value<cur->element){
            cur = cur->left;
        }else if(value>cur->element){
            cur = cur->right;
        }else{
            break;
        }
    }
    if(cur) splay(cur);
    return root;
}
template <class T>
SPTNode<T>* SPTree<T>::findMin(SPTNode<T> *tree) const {
    if(!tree) return nullptr;
    while(tree->left) tree = tree->left;
    return tree;
}
template <class T>
void SPTree<T>::insert(const T &value) {
    if(!this->root){
        this->root = new SPTNode<T>(value, nullptr);
    }else{
        insert(value,this->root);
    }
}
template <class T>
void SPTree<T>::insert(const T &value, SPTNode<T> *parent) {
    SPTNode<T>* newOne = nullptr;
    if(value<parent->element){
        if(parent->left == nullptr){
            newOne = parent->left = new SPTNode<T>(value,parent);
        }else{
            insert(value,parent->left);
        }
    }else if(value>parent->element){
        if(parent->right == nullptr){
            newOne = parent->right = new SPTNode<T>(value,parent);
        }else{
            insert(value,parent->right);
        }
    }else{
        return ;
    }
    splay(newOne);
}
template <class T>
void SPTree<T>::replace(SPTNode<T> *ori, SPTNode<T> *to) {
    if(ori->parent==nullptr)
        this->root = to;
    else if(ori == ori->parent->left)
        ori->parent->left = to;
    else
        ori->parent->right = to;
    if(to != nullptr) to->parent = ori->parent;
}
template <class T>
void SPTree<T>::remove(const T &value) {
    if(!this->root) return ;
    SPTNode<T>* cur = this->root;
    while(cur != nullptr){
        if(cur->element == value) break;
        else if(value<cur->element){
            cur = cur->left;
        }else{
            cur = cur->right;
        }
    }
    if(cur) {
      splay(cur);
      remove(cur);
    }
      
}
template <class T>
void SPTree<T>::remove(SPTNode<T> *&target) {
    if(!target->left) replace(target,target->right);
    else if(!target->right) replace(target,target->left);
    else{
        SPTNode<T>* child = findMin(target->right);
        if(child->parent != target){
            replace(child,child->right);
            child->right = target->right;
            child->right->parent = child;
        }
        replace(target,child);
        child->left = target->left;
        child->left->parent = child;
    }
    delete target;
}


template <class T>
void SPTree<T>::printTree(const int &code) {
    switch(code){
        case PREORDER:
            preorder(this->root);
            break;
        case INORDER:
            inorder(this->root);
            break;
        case POSTORDER:
            postorder(this->root);
            break;
        default:break;
    }
    std::cout<<std::endl;
}
template <class T>
void SPTree<T>::inorder(const SPTNode<T> *tree) const {
    if(tree){
        inorder(tree->left);
        std::cout<<tree->element<<' ';
        inorder(tree->right);
    }
}
template <class T>
void SPTree<T>::preorder(const SPTNode<T> *tree) const {
    if(tree){
        std::cout<<tree->element<<' ';
        preorder(tree->left);
        preorder(tree->right);
    }
}
template <class T>
void SPTree<T>::postorder(const SPTNode<T> *tree) const {
    if(tree){
        postorder(tree->left);
        postorder(tree->right);
        std::cout<<tree->element<<' ';
    }
}
template <class T>
void SPTree<T>::makeEmpty() {
    makeEmpty(root);
}
template <class T>
void SPTree<T>::makeEmpty(SPTNode<T> *&tree) {
    if(!tree) return;
    if(tree->left)makeEmpty(tree->left);
    if(tree->right)makeEmpty(tree->right);
    delete tree;
    tree = nullptr;
}

#endif //MYOOP_SPLAYTREE_H

chnmagnus
71 声望15 粉丝

于代码中打滚卖萌ing