红黑树的C++实现

#ifndef RBTree_H
#define RBTree_H

#include <stack>
using namespace std;

#define RED 0
#define BLACK 1


template< typename T>
class TreeNode
{
public:
  T value;
  TreeNode<T> * parent;
  TreeNode<T> * left;
  TreeNode<T> * right;
  int color;

  TreeNode() // No-arg constructor
  {
    left = NULL;
    right = NULL;
    parent = NULL;
    color = RED;
  }

  TreeNode(T value) // Constructor
  {
    this->value = value;
    left = NULL;
    right = NULL;
    parent = NULL;
    color = RED;
  }
};


template < typename T >
class RBTree
{
public:
  int treeSize;
  RBTree();
  RBTree(T values[],int arraySize);
  int insert(T value);
  void inOrder();
  void inOrderNorRec();
  int deleteNode(T value);
  int successor(T value);
  int predecessor(T value);
  int maxValue();
  int minValue();
  int getSize(T value);
  int getHeight();
  void output();

private:
  TreeNode<T> * treeroot;
  TreeNode<T> * treetail;
  void LeftRotate(TreeNode<T> * target);
  void RightRotate(TreeNode<T> * target);
  void LeftRightRotate(TreeNode<T> * target);
  void RightLeftRotate(TreeNode<T> * target);
  int insert(TreeNode<T> * targetParent,TreeNode<T> * target,T value);
  void insertFixUp(TreeNode<T> *target);
  int deleteNode(TreeNode<T> *target);
  void deleteNodeFixUp(TreeNode<T> *fixNode);
  void inOrder(TreeNode<T> *target);
  void inOrderNorRec(TreeNode<T> *target);
  TreeNode<T> * search(T searchvalue);
  TreeNode<T> * successor(TreeNode<T> *target);
  TreeNode<T> * predecessor(TreeNode<T> *target);
  TreeNode<T> * maxValue(TreeNode<T> *target);
  TreeNode<T> * minValue(TreeNode<T> *target);
  int getSize(TreeNode<T> *target);
  int getHeight(TreeNode<T> *target);
  void output(TreeNode<T> *target,int totalSpaces);
};


template <typename T>
RBTree<T>::RBTree()
{
  this->treetail = new TreeNode<T>();
  this->treetail->color = BLACK;
  this->treeroot = this->treetail;
  this->treeSize = 0;
}


template < typename T >
RBTree<T>::RBTree(T values[],int arraySize)
{
  this->treetail = new TreeNode<T>();
  this->treetail->color = BLACK;
  this->treeroot = this->treetail;
  this->treeSize = 0;

  for(int i=0 ; i<arraySize ; i++){
    this->insert(this->treeroot,this->treeroot,values[i]);
  }
}


template< typename T >
void RBTree<T>::LeftRotate(TreeNode<T> * target)
{
   TreeNode<T> *rightchild = target->right;
   target->right = rightchild->left;
   if (rightchild->left != this->treetail){
    rightchild->left->parent = target;
   }

   if (target->parent == this->treetail){
    this->treeroot = rightchild;
    rightchild->parent = this->treetail;
    rightchild->color = BLACK;
   }else if(target->parent->left == target){
    target->parent->left = rightchild;
    rightchild->parent = target->parent;
   }else{
    target->parent->right = rightchild;
    rightchild->parent = target->parent;
   }
   
   rightchild->left = target;
   target->parent = rightchild;

}


template< typename T >
void RBTree<T>::RightRotate(TreeNode<T> * target)
{
  {
   TreeNode<T> *leftchild = target->left;
   target->left = leftchild->right;
   if (leftchild->right != this->treetail){
    leftchild->left->parent = target;
   }

   if (target->parent == this->treetail){
    this->treeroot = leftchild;
    leftchild->parent = this->treetail;
    leftchild->color = BLACK;
   }else if(target->parent->left == target){
    target->parent->left = leftchild;
    leftchild->parent = target->parent;
   }else{
    target->parent->right = leftchild;
    leftchild->parent = target->parent;
   }

   leftchild->right = target;
   target->parent = leftchild;

 }
}


template <typename T>
int RBTree<T>::insert(T value)
{
  this->insert(this->treeroot,this->treeroot,value);
  return 0;
}


template <typename T>
int RBTree<T>::insert(TreeNode<T> * targetParent,TreeNode<T> * target,T value)
{
  if (this->treeroot == this->treetail){
    this->treeroot = new TreeNode<T>(value); 
    this->treeroot->color = BLACK;
    this->treeroot->parent = this->treetail;
    this->treeroot->left = this->treetail;
    this->treeroot->right = this->treetail;
  } 
  else
  {
    TreeNode<T> *former = NULL;
    TreeNode<T> *current = this->treeroot;
    while (current != this->treetail){
      if (value < current->value){
        former = current;
        current = current->left;
      }
      else if (value > current->value){
        former = current;
        current = current->right;
      }
      else{
        cout << "Node with value "<< value <<" has existed." <<endl;
        return 1;
      }
    }

    TreeNode<T> *newNode = new TreeNode<T>(value);
    newNode->parent = former;
    newNode->left = this->treetail;
    newNode->right = this->treetail;
    if (value < former->value){
      former->left = newNode;
    }
    else if(value > former->value){
      former->right = newNode;
    }

    this->insertFixUp(newNode);
  }

  this->treeSize++;
  return 0;
}

template <typename T>
void RBTree<T>::insertFixUp(TreeNode<T> *target)
{
  while(target != this->treeroot && target->parent->color == RED){
    if(target->parent == target->parent->parent->left){
      TreeNode<T> *uncle =target->parent->parent->right;
      if (uncle->color == RED){
        target->parent->parent->color = RED;
        target->parent->color = BLACK;
        uncle->color = BLACK;
        target = target->parent->parent;
      }else{
        if(target->parent->right == target){
          target = target->parent;
          this->LeftRotate(target);
        }
        target->parent->color= BLACK;
        target->parent->parent->color= RED;
        this->RightRotate(target->parent->parent);
        break;
      }
    }
    else if(target->parent == target->parent->parent->right){
      TreeNode<T> *uncle =target->parent->parent->left;
      if (uncle->color == RED){
        target->parent->parent->color = RED;
        target->parent->color = BLACK;
        uncle->color = BLACK;
        target = target->parent->parent;
      }else{
        if(target->parent->left == target){
          target = target->parent;
          this->RightRotate(target);
        }
        target->parent->color= BLACK;
        target->parent->parent->color= RED;
        this->LeftRotate(target->parent->parent);
        break;
      }
    }
  }

  this->treeroot->color = BLACK;

}

template <typename T>
TreeNode<T> * RBTree<T>::search(T searchvalue)
{
  TreeNode<T> *current = this->treeroot;
  int find =0;
  while (current != this->treetail && find == 0){
    if (current->value == searchvalue){
      find = 1;
    }
    else if(current->value > searchvalue){
      current = current->left;
    }else{
      current = current->right;
    }
  }

  if (find == 1){
    return current;
  }else{
    return this->treetail;
  }
}


template <typename T>
int RBTree<T>::deleteNode(T value){
  TreeNode<T> *delNode = this->search(value);
  if ( delNode == this->treetail){
    cout << "not find " << endl;
    return 1;
  }

  this->deleteNode(delNode);
  cout << "Node "<< value <<" has been deleted."<< endl;
  return 0;
}


template <typename T>
int RBTree<T>::deleteNode(TreeNode<T> *delNode){
  TreeNode<T> *deleteTarget;
  if (delNode->left == this->treetail && delNode->right == this->treetail){
    deleteTarget = delNode;
  }else if(delNode->left != this->treetail){
    deleteTarget = this->predecessor(delNode);
  }else if(delNode->right != this->treetail){
    deleteTarget = this->successor(delNode);
  }

  TreeNode<T> *deleteTargetChild = this->treetail;
  if (deleteTarget->left != this->treetail){
    deleteTargetChild = deleteTarget->left;
  }else if (deleteTarget->right != this->treetail){
    deleteTargetChild = deleteTarget->right;
  }

  deleteTargetChild->parent = deleteTarget->parent;

  if (deleteTarget->parent == this->treetail){
    this->treeroot = deleteTargetChild;
    deleteTargetChild->parent = this->treetail;
    deleteTargetChild->color = BLACK;
  }else if ( deleteTarget->parent->left == deleteTarget){
    deleteTarget->parent->left = deleteTargetChild;
  }else{
    deleteTarget->parent->right = deleteTargetChild;
  }

  if (deleteTarget != delNode){
    delNode->value = deleteTarget->value;
  }

  //Delete_Fixup
  if(deleteTarget->color == BLACK){
    if(deleteTargetChild->color == RED){
      deleteTargetChild->color = BLACK;
    }else{
      this->deleteNodeFixUp(deleteTargetChild);
    }
  }

  this->treeSize--;
  return 0;
}


template <typename T>
void RBTree<T>::deleteNodeFixUp(TreeNode<T> *fixNode){
  TreeNode<T> *brother = NULL;
  while(fixNode != this->treeroot && fixNode->color == BLACK){
    if(fixNode->parent->left == fixNode){
      brother = fixNode->parent->right;
      if(brother->color == RED){
        brother->color = BLACK;
        fixNode->parent->color = RED;
        this->LeftRotate(fixNode->parent);
        brother = fixNode->parent->right;
      }else if(brother->left->color == BLACK && brother->right->color == BLACK){
        brother->color = RED;
        fixNode = fixNode->parent;
      }else{
        if(brother->right->color == BLACK){
          brother->color = RED;
          brother->left->color = BLACK;
          this->RightRotate(brother);
          brother = fixNode->parent->right;
        }
        fixNode->parent->color = BLACK;
        brother->color = RED;
        brother->right->color = BLACK;
        this->LeftRotate(fixNode->parent);
        break;
      }
    }
    else{
      brother = fixNode->parent->left;
      if(brother->color == RED){
        brother->color = BLACK;
        fixNode->parent->color = RED;
        this->RightRotate(fixNode->parent);
        brother = fixNode->parent->left;
      }else if(brother->left->color == BLACK && brother->right->color == BLACK){
        brother->color = RED;
        fixNode = fixNode->parent;
      }else{
        if(brother->right->color == BLACK){
          brother->color = RED;
          brother->right->color = BLACK;
          this->LeftRotate(brother);
          brother = fixNode->parent->left;
        }
        fixNode->parent->color = BLACK;
        brother->color = RED;
        brother->left->color = BLACK;
        this->RightRotate(fixNode->parent);
        break;
      }
    }
  }
  fixNode->color = BLACK;
}

template <typename T>
int RBTree<T>::successor(T value)
{
  TreeNode<T> *position = this->search(value);
  if ( position == this->treetail){
    cout << "not find " << endl;
    return 1;
  }
  TreeNode<T> *successorNode = this->successor(position);
  if ( successorNode != this->treetail)
    cout << value << " \'s successor is:" << successorNode->value << endl;
  else
    cout << value << " has no successor" << endl;
  return 0;
}


template <typename T>
TreeNode<T> * RBTree<T>::successor(TreeNode<T> *target)
{
  if ( target->right != this->treetail){
    return minValue(target->right);
  }
  TreeNode<T> * parentNode =target->parent;
  while ( parentNode != this->treetail && parentNode->right == target){
    target = parentNode;
    parentNode = parentNode->parent;
  }
  return parentNode;
}


template <typename T>
int RBTree<T>::predecessor(T value)
{
  TreeNode<T> *position = this->search(value);
  if ( position == this->treetail){
    cout << "Can\'t find " << value <<" in AVL tree." <<endl;
    return 1;
  }
  TreeNode<T> *predecessorNode = this->predecessor(position);
  if ( predecessorNode != this->treetail)
    cout << value << " \'s predecessor is:" << predecessorNode->value << endl;
  else
    cout << value << " has no predecessor" << endl;
  return 0;
}


template <typename T>
TreeNode<T> * RBTree<T>::predecessor(TreeNode<T> *target)
{
  if ( target->left != this->treetail){
    return maxValue(target->left);
  }
  TreeNode<T> * parentNode =target->parent;
  while ( parentNode != this->treetail && parentNode->left == target){
    target = parentNode;
    parentNode = parentNode->parent;
  }
  return parentNode;
}


template <typename T>
int RBTree<T>::maxValue()
{
  TreeNode<T> * max = this->maxValue(this->treeroot);
  return max->value;
}


template <typename T>
TreeNode<T> * RBTree<T>::maxValue(TreeNode<T> *target)
{
  while (target -> right != this->treetail){
    target = target -> right;
  }
  return target;
}


template <typename T>
int RBTree<T>::minValue()
{
  TreeNode<T> * min = this->minValue(this->treeroot);
  return min->value;
}


template <typename T>
TreeNode<T> * RBTree<T>::minValue(TreeNode<T> *target)
{
  while (target -> left != this->treetail){
    target = target -> left;
  }
  return target;
}


template <typename T>
int RBTree<T>::getHeight()
{
  return this->getHeight(this->treeroot);
}


template <typename T>
int RBTree<T>::getHeight(TreeNode<T> *target)
{
  if(target == this->treetail){
    return -1;
  }else{
    int leftHeight = this->getHeight(target->left);
    int rightHeight = this->getHeight(target->right);
    int targetHeight = (leftHeight >= rightHeight)? leftHeight+1:rightHeight+1;
    return targetHeight;
  }
}


template <typename T>
int RBTree<T>::getSize(T value)
{
  TreeNode<T> *target = this->search(value);
  return getSize(target);
}


template <typename T>
int RBTree<T>::getSize(TreeNode<T> *target)
{
  if (target == this->treetail){
    return 0;
  }

  if (target->left == this->treetail && target->left == this->treetail){
    return 1;
  }else {
    return this->getSize(target->left) + 1 + this->getSize(target->right);
  }
}


template <typename T>
void RBTree<T>::inOrder()
{
  inOrder(this->treeroot);
  cout << endl;
}


template <typename T>
void RBTree<T>::inOrder(TreeNode<T> *target)
{
  if (target == this->treetail)
    return ;
  inOrder(target->left);
  cout << target->value << " ";
  inOrder(target->right);
}


template <typename T>
void RBTree<T>::inOrderNorRec()
{
  inOrderNorRec(this->treeroot);
  cout << endl;
}


template <typename T>
void RBTree<T>::inOrderNorRec(TreeNode<T> *target)
{
  stack < TreeNode<T> *> s;
  while ((target != this->treetail) || !s.empty())
  {
      if (target != this->treetail)
      {
          s.push(target);
          target = target->left;
      }
      else
      {
          target = s.top();
          cout << target->value << " ";
          s.pop();
          target = target->right;
      }
  }
}


template <typename T>
void RBTree<T>::output()
{
    output(this->treeroot,0);
}

template <typename T>
void RBTree<T>::output(TreeNode<T> *target,int totalSpaces)
{
    if(target != this->treetail)
    {
        output(target->right,totalSpaces+4);
        for(int i=0; i<totalSpaces; i++){
          cout<<' ';
        }
        if (target->parent != this->treetail){
          if(target->color == BLACK){
            cout << target->value  << "[" << target->parent->value << "]"  << "[B]"  << endl;
          }else{
            cout << target->value   << "[" << target->parent->value << "]" << "[R]"  << endl;
          }
        }
        else{
          cout << target->value << "[ROOT]" << "[" << target->color << "]" << endl;
        }
        output(target->left,totalSpaces+4);
    }
};

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值