首页 > 其他分享 >红黑树

红黑树

时间:2023-06-27 16:23:52浏览次数:19  
标签:Node right parent color Color 红黑树 left

#include <iostream>

enum class Color {
  Red,
  Black
};

template <typename T>
struct Node {
  T key;
  Node<T>* parent;
  Node<T>* left;
  Node<T>* right;
  Color color;

  Node(T k) : key(k), parent(nullptr), left(nullptr), right(nullptr), color(Color::Red) {}
};

template <typename T>
class RedBlackTree {
 private:
  Node<T>* root;

  // 左旋
  void leftRotate(Node<T>* x);
  // 右旋
  void rightRotate(Node<T>* x);
  // 插入修正
  void insertFixup(Node<T>* z);
  // 将子树 u 替换为子树 v
  void transplant(Node<T>* u, Node<T>* v);
  // 求 x 的子树的最小值点
  Node<T>* minimum(Node<T>* x);
  // 删除修正
  void deleteFixup(Node<T>* x);

 public:
  RedBlackTree() : root(nullptr) {}
  // 插入
  void insert(T key);
  // 删除
  void remove(T key);
  // 查找
  Node<T>* search(T key);
  // 中序遍历
  void printInOrder(Node<T>* node);
  void printInOrderTraversal();
};

template <typename T>
void RedBlackTree<T>::leftRotate(Node<T>* x) {
  Node<T>* y = x->right;
  x->right = y->left;
  if (y->left != nullptr) {
    y->left->parent = x;
  }
  y->parent = x->parent;
  if (x->parent == nullptr) {
    root = y;
  } else if (x == x->parent->left) {
    x->parent->left = y;
  } else {
    x->parent->right = y;
  }
  y->left = x;
  x->parent = y;
}

template <typename T>
void RedBlackTree<T>::rightRotate(Node<T>* x) {
  Node<T>* y = x->left;
  x->left = y->right;
  if (y->right != nullptr) {
    y->right->parent = x;
  }
  y->parent = x->parent;
  if (x->parent == nullptr) {
    root = y;
  } else if (x == x->parent->right) {
    x->parent->right = y;
  } else {
    x->parent->left = y;
  }
  y->right = x;
  x->parent = y;
}

template <typename T>
void RedBlackTree<T>::insertFixup(Node<T>* z) {
  while (z->parent != nullptr && z->parent->color == Color::Red) {
    if (z->parent == z->parent->parent->left) {
      Node<T>* y = z->parent->parent->right;
      if (y != nullptr && y->color == Color::Red) {
        z->parent->color = Color::Black;
        y->color = Color::Black;
        z->parent->parent->color = Color::Red;
        z = z->parent->parent;
      } else {
        if (z == z->parent->right) {
          z = z->parent;
          leftRotate(z);
        }
        z->parent->color = Color::Black;
        z->parent->parent->color = Color::Red;
        rightRotate(z->parent->parent);
      }
    } else {
      Node<T>* y = z->parent->parent->left;
      if (y != nullptr && y->color == Color::Red) {
        z->parent->color = Color::Black;
        y->color = Color::Black;
        z->parent->parent->color = Color::Red;
        z = z->parent->parent;
      } else {
        if (z == z->parent->left) {
          z = z->parent;
          rightRotate(z);
        }
        z->parent->color = Color::Black;
        z->parent->parent->color = Color::Red;
        leftRotate(z->parent->parent);
      }
    }
  }
  root->color = Color::Black;
}

template <typename T>
void RedBlackTree<T>::transplant(Node<T>* u, Node<T>* v) {
  if (u->parent == nullptr) {
    root = v;
  } else if (u ==u->parent->left) {
    u->parent->left = v;
  } else {
    u->parent->right = v;
  }
  if (v != nullptr) {
    v->parent = u->parent;
  }
}

template <typename T>
Node<T>* RedBlackTree<T>::minimum(Node<T>* x) {
  while (x->left != nullptr) {
    x = x->left;
  }
  return x;
}

template <typename T>
void RedBlackTree<T>::deleteFixup(Node<T>* x) {
  while (x != root && (x == nullptr || x->color == Color::Black)) {
    if (x == x->parent->left) {
      Node<T>* w = x->parent->right;
      if (w->color == Color::Red) {
        w->color = Color::Black;
        x->parent->color = Color::Red;
        leftRotate(x->parent);
        w = x->parent->right;
      }
      if ((w->left == nullptr || w->left->color == Color::Black) &&
          (w->right == nullptr || w->right->color == Color::Black)) {
        w->color = Color::Red;
        x = x->parent;
      } else {
        if (w->right == nullptr || w->right->color == Color::Black) {
          if (w->left != nullptr) {
            w->left->color = Color::Black;
          }
          w->color = Color::Red;
          rightRotate(w);
          w = x->parent->right;
        }
        w->color = x->parent->color;
        x->parent->color = Color::Black;
        if (w->right != nullptr) {
          w->right->color = Color::Black;
        }
        leftRotate(x->parent);
        x = root;  // 退出循环
      }
    } else {
      Node<T>* w = x->parent->left;
      if (w->color == Color::Red) {
        w->color = Color::Black;
        x->parent->color = Color::Red;
        rightRotate(x->parent);
        w = x->parent->left;
      }
      if ((w->right == nullptr || w->right->color == Color::Black) &&
          (w->left == nullptr || w->left->color == Color::Black)) {
        w->color = Color::Red;
        x = x->parent;
      } else {
        if (w->left == nullptr || w->left->color == Color::Black) {
          if (w->right != nullptr) {
            w->right->color = Color::Black;
          }
          w->color = Color::Red;
          leftRotate(w);
          w = x->parent->left;
        }
        w->color = x->parent->color;
        x->parent->color = Color::Black;
        if (w->left != nullptr) {
          w->left->color = Color::Black;
        }
        rightRotate(x->parent);
        x = root;
      }
    }
  }
  if (x != nullptr) {
    x->color = Color::Black;
  }
}

template <typename T>
void RedBlackTree<T>::insert(T key) {
  Node<T>* z = new Node<T>(key);
  Node<T>* y = nullptr;
  Node<T>* x = root;
  while (x != nullptr) {
    y = x;
    if (z->key < x->key) {
      x = x->left;
    } else {
      x = x->right;
    }
  }
  z->parent = y;
  if (y == nullptr) {
    root = z;
  } else if (z->key < y->key) {
    y->left = z;
  } else {
    y->right = z;
  }
  insertFixup(z);
}

template <typename T>
Node<T>* RedBlackTree<T>::search(T key) {
  Node<T>* current = root;
  while (current != nullptr && current->key != key) {
    if (key < current->key) {
      current = current->left;
    } else {
      current = current->right;
    }
  }
  return current;
}

template <typename T>
void RedBlackTree<T>::remove(T key) {
  Node<T>* z = search(key);
  if (z == nullptr) {
    return;
  }
  Node<T>* x;
  Node<T>* y = z;
  Color originalColor = y->color;
  if (z->left == nullptr) {
    x = z->right;
    transplant(z, z->right);
  } else if (z->right == nullptr) {
    x = z->left;
    transplant(z, z->left);
  } else {
    y = minimum(z->right);
    originalColor = y->color;
    x = y->right;
    if (y->parent == z) {
      if (x != nullptr) {
        x->parent = y;
      }
    } else {
      transplant(y, y->right);
      y->right = z->right;
      y->right->parent = y;
    }
    transplant(z, y);
    y->left = z->left;
    y->left->parent = y;
    y->color = z->color;
  }
  if (originalColor == Color::Black) {
    deleteFixup(x);
  }
  delete z;
}

template <typename T>
void RedBlackTree<T>::printInOrder(Node<T>* node) {
  if (node != nullptr) {
    printInOrder(node->left);
    std::cout << node->key << " ";
    printInOrder(node->right);
  }
}

template <typename T>
void RedBlackTree<T>::printInOrderTraversal() {
  printInOrder(root);
  std::cout << std::endl;
}

int main() {
  RedBlackTree<int> tree;
  tree.insert(10);
  tree.insert(20);
  tree.insert(30);
  tree.insert(15);
  tree.insert(5);
  std::cout << "In-order traversal: ";
  tree.printInOrderTraversal();

  tree.remove(20);

  std::cout << "In-order traversal after removing 20: ";
  tree.printInOrderTraversal();

  return 0;
}

标签:Node,right,parent,color,Color,红黑树,left
From: https://www.cnblogs.com/hacker-dvd/p/17509186.html

相关文章

  • 5分钟了解二叉树之红黑树
    转载请注明出处:https://i.cnblogs.com/posts/edit;postId=16032891 书接上一回。上一篇已经讲解到了AVL树,这一篇会接着讲另一个重量级的数据结构:红黑树。红黑树红黑树是一种自平衡二叉搜索树。每个节点存储一个表示“颜色”(“红色”或“黑色”)的额外位,用于确保树在插入和删......
  • 左倾红黑树 (LLRB)
    简介红黑树是平衡二叉查找树的一种,前面我们提到,非平衡的BST,在只有随机插入和查询的情况下,时间复杂度是$O(\logn)$的,然而,如果同时存在随机插入和随机删除,那么时间复杂度会退化到$O(\sqrtn)$,这是我们无法接受的。红黑树在插入和删除时,会维持树的平衡,即保证树的高度在$[\log......
  • 红黑树
    简介红黑树是平衡二叉查找树的一种,前面我们提到,非平衡的BST,在只有随机插入和查询的情况下,时间复杂度是$O(\logn)$的,然而,如果同时存在随机插入和随机删除,那么时间复杂度会退化到$O(\sqrtn)$,这是我们无法接受的。红黑树在插入和删除时,会维持树的平衡,即保证树的高度在$[\log......
  • 数据结构和算法系列课程(01)--- 排序二叉树和红黑树
    把排序二叉树放在这个系列课程的第一个部分似乎有些唐突,但是考虑到它在面试中出现的可能性,把它放在这样的一个位置也就不足为奇了。关于树和二叉树的基础知识,可以到下面的链接中下载我的课件进行了解。下面给出一个排序二叉树的Java实现:packagcom.loonstudio;/***排序二叉树......
  • C#数据结构-红黑树实现
    参考网址: https://zhuanlan.zhihu.com/p/353948322二叉查找树,他对于大多数情况下的查找和插入在效率上来说是没有问题的,但是他在最差的情况下效率比较低。红黑树保证在最坏的情况下插入和查找效率都能保证在对数的时间复杂度内完成。红黑树的性质:性质1.节点是红色或黑色性质2.根是......
  • hashmap怎么解决哈希冲突问题?红黑树和AVL树有何区别?
    链地址法hashmap是一种基于数组和链表(或红黑树)的数据结构,它可以通过hash函数将任意长度的键映射到一个固定长度的索引,从而实现快速的存取操作。但是,由于hash函数的结果是有限的,而键的数量是无限的,所以可能存在不同的键映射到同一个索引的情况,这就叫做哈希冲突。为了解决哈希冲突,has......
  • java面试 关于红黑树
    红黑树(Red-BlackTree):是一种自平衡的二叉搜索树,它在实际的软件开发中广泛应用。红黑树的特点是具有高效的插入、删除和查找操作,并且保持树的平衡,以保证这些操作的时间复杂度为O(logn)。红黑树与AVL树有什么区别?红黑树和AVL树都是自平衡的二叉搜索树,但它们在维护平衡方......
  • CS61B_红黑树转换
        ......
  • 万字长文之HashMap源码解析(包含红黑树)
    〇、储备知识之红黑树0.1>2-3树红黑树是一种自平衡的二叉树,它可以避免二分搜索树在极端的情况下蜕化成链表的情况。那么什么是红黑树呢?要想便于了解红黑树,我们先了解一下跟它息息相关的2-3树。2-3树是一种绝对平衡的多叉树,在这棵树中,任意一个节点,它的左右子树的高度是相同的。如下......
  • 红黑树是怎么来的
    平衡的关键书接前文。在前文《二叉搜索树的本质》中我们提到,二叉搜索树在实践中有个很大的问题:树倾斜。按如下顺序插入数据会让二叉搜索树退化成普通链表,进而相关操作的时间复杂度退化到O(n):怎样让这棵树在写操作后仍然保持平衡呢?R教授一边呷着黑咖啡,一边盯着这棵“畸形”......