广告
返回顶部
首页 > 资讯 > 精选 >java算法如何实现红黑树
  • 667
分享到

java算法如何实现红黑树

java 2023-05-30 22:05:30 667人浏览 薄情痞子
摘要

这篇文章主要介绍了java算法如何实现红黑树,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。红黑树定义红黑树(英语:Red–black tree)是一种自平衡二叉查找树,是在计

这篇文章主要介绍了java算法如何实现红黑树,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

红黑树

定义

红黑树(英语:Red–black tree)是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组

红黑树的另一种定义是含有红黑链接并满足下列条件的二叉查找树:

红链接均为左链接;没有任何一个结点同时和两条红链接相连;该树是完美黑色平衡的,即任意空链接到根结点的路径上的黑链接数量相同。

满足这样定义的红黑树和相应的2-3树是一一对应的。

java算法如何实现红黑树

旋转

旋转又分为左旋和右旋。通常左旋操作用于将一个向右倾斜的红色链接旋转为向左链接。对比操作前后,可以看出,该操作实际上是将红线链接的两个节点中的一个较大的节点移动到根节点上。

左旋操作如下图:

java算法如何实现红黑树

右旋旋操作如下图:

java算法如何实现红黑树

即:

java算法如何实现红黑树

复杂度

红黑树的平均高度大约为lgN。

下图是红黑树在各种情况下的时间复杂度,可以看出红黑树是2-3查找树的一种实现,他能保证最坏情况下仍然具有对数的时间复杂度。

java算法如何实现红黑树

Java代码

import java.util.NoSuchElementException;import java.util.Scanner;public class RedBlackBST<key extends="" key="">, Value> {  private static final boolean RED = true;  private static final boolean BLACK = false;  private node root; //root of the BST  private class Node {    private Key key;      //key    private Value val;     //associated data    private Node left, right;  //links to left and right subtrees    private boolean color;   //color of parent link    private int size;      //subtree count    public Node(Key key, Value val, boolean color, int size) {      this.key = key;      this.val = val;      this.color = color;      this.size = size;    }  }  //is node x red?  private boolean isRed(Node x) {    if(x == null) {      return false;    }    return x.color == RED;  }  //number of node in subtree rooted at x; 0 if x is null  private int size(Node x) {    if(x == null) {      return 0;    }    return x.size;  }      public int size() {    return size(root);  }    public boolean isEmpty() {    return root == null;  }    public Value get(Key key) {    if(key == null) {      throw new NullPointerException("argument to get() is null");    }    return get(root, key);  }  //value associated with the given key in subtree rooted at x; null if no such key  private Value get(Node x, Key key) {    while(x != null) {      int cmp = key.compareTo(x.key);      if(cmp < 0) {        x = x.left;      }      else if(cmp > 0) {        x = x.right;      }      else {        return x.val;      }            }    return null;  }    public boolean contains(Key key) {    return get(key) != null;  }      public void put(Key key, Value val) {    if (key == null) {      throw new NullPointerException("first argument to put() is null");    }    if (val == null) {      delete(key);      return;    }    root = put(root, key, val);    root.color = BLACK;      }  // insert the key-value pair in the subtree rooted at h  private Node put(Node h, Key key, Value val) {    if(h == null) {      return new Node(key, val, RED, 1);    }    int cmp = key.compareTo(h.key);    if(cmp < 0) {      h.left = put(h.left, key, val);    }    else if(cmp > 0) {      h.right = put(h.right, key, val);    }    else {      h.val = val;    }    if(isRed(h.right) && !isRed(h.left)) {      h = rotateLeft(h);    }    if(isRed(h.left) && isRed(h.left.left)) {      h = rotateRight(h);    }    if(isRed(h.left) && isRed(h.right)) {      flipColors(h);    }    h.size = size(h.left) + size(h.right) + 1;    return h;  }       public void deleteMin() {    if (isEmpty()) {      throw new NoSuchElementException("BST underflow");    }    // if both children of root are black, set root to red    if (!isRed(root.left) && !isRed(root.right))      root.color = RED;    root = deleteMin(root);    if (!isEmpty()) root.color = BLACK;    // assert check();  }  // delete the key-value pair with the minimum key rooted at h  // delete the key-value pair with the minimum key rooted at h  private Node deleteMin(Node h) {     if (h.left == null){      return null;    }    if (!isRed(h.left) && !isRed(h.left.left)) {      h = moveRedLeft(h);    }    h.left = deleteMin(h.left);    return balance(h);  }    public void deleteMax() {    if (isEmpty()) {      throw new NoSuchElementException("BST underflow");    }    // if both children of root are black, set root to red    if (!isRed(root.left) && !isRed(root.right))      root.color = RED;    root = deleteMax(root);    if (!isEmpty()) root.color = BLACK;    // assert check();  }  // delete the key-value pair with the maximum key rooted at h  // delete the key-value pair with the maximum key rooted at h  private Node deleteMax(Node h) {       if (isRed(h.left))        h = rotateRight(h);      if (h.right == null)        return null;      if (!isRed(h.right) && !isRed(h.right.left))        h = moveRedRight(h);      h.right = deleteMax(h.right);      return balance(h);    }    public void delete(Key key) {    if (key == null) {      throw new NullPointerException("argument to delete() is null");    }    if (!contains(key)) {      return;    }    //if both children of root are black, set root to red    if(!isRed(root.left) && !isRed(root.right)) {      root.color = RED;    }    root = delete(root, key);    if(!isEmpty()) {      root.color = BLACK;    }  }  // delete the key-value pair with the given key rooted at h  // delete the key-value pair with the given key rooted at h  private Node delete(Node h, Key key) {    if(key.compareTo(h.key) < 0) {      if(!isRed(h.left) && !isRed(h.left.left)) {        h = moveRedLeft(h);      }      h.left = delete(h.left, key);    }    else {      if(isRed(h.left)) {        h = rotateRight(h);      }      if (key.compareTo(h.key) == 0 && (h.right == null)) {        return null;      }      if (!isRed(h.right) && !isRed(h.right.left)) {        h = moveRedRight(h);      }      if (key.compareTo(h.key) == 0) {        Node x = min(h.right);        h.key = x.key;        h.val = x.val;        h.right = deleteMin(h.right);      }      else {        h.right = delete(h.right, key);      }    }    return balance(h);  }    // make a left-leaning link lean to the right  // make a left-leaning link lean to the right  private Node rotateRight(Node h) {    // assert (h != null) && isRed(h.left);    Node x = h.left;    h.left = x.right;    x.right = h;    x.color = x.right.color;    x.right.color = RED;    x.size = h.size;    h.size = size(h.left) + size(h.right) + 1;    return x;  }  // make a right-leaning link lean to the left  // make a right-leaning link lean to the left  private Node rotateLeft(Node h) {    // assert (h != null) && isRed(h.right);    Node x = h.right;    h.right = x.left;    x.left = h;    x.color = x.left.color;    x.left.color = RED;    x.size = h.size;    h.size = size(h.left) + size(h.right) + 1;    return x;  }  // flip the colors of a node and its two children  // flip the colors of a node and its two children  private void flipColors(Node h) {    // h must have opposite color of its two children    // assert (h != null) && (h.left != null) && (h.right != null);    // assert (!isRed(h) && isRed(h.left) && isRed(h.right))    //  || (isRed(h) && !isRed(h.left) && !isRed(h.right));    h.color = !h.color;    h.left.color = !h.left.color;    h.right.color = !h.right.color;  }  // Assuming that h is red and both h.left and h.left.left  // are black, make h.left or one of its children red.  // Assuming that h is red and both h.left and h.left.left  // are black, make h.left or one of its children red.  private Node moveRedLeft(Node h) {    // assert (h != null);    // assert isRed(h) && !isRed(h.left) && !isRed(h.left.left);    flipColors(h);    if (isRed(h.right.left)) {       h.right = rotateRight(h.right);      h = rotateLeft(h);      flipColors(h);    }    return h;  }  // Assuming that h is red and both h.right and h.right.left  // are black, make h.right or one of its children red.  // Assuming that h is red and both h.right and h.right.left  // are black, make h.right or one of its children red.  private Node moveRedRight(Node h) {    // assert (h != null);    // assert isRed(h) && !isRed(h.right) && !isRed(h.right.left);    flipColors(h);    if (isRed(h.left.left)) {       h = rotateRight(h);      flipColors(h);    }    return h;  }  // restore red-black tree invariant  // restore red-black tree invariant  private Node balance(Node h) {    // assert (h != null);    if (isRed(h.right)) {      h = rotateLeft(h);    }    if (isRed(h.left) && isRed(h.left.left)) {      h = rotateRight(h);    }    if (isRed(h.left) && isRed(h.right)) {      flipColors(h);    }    h.size = size(h.left) + size(h.right) + 1;    return h;  }        public int height() {     return height(root);   }   private int height(Node x) {     if (x == null) {       return -1;     }     return 1 + Math.max(height(x.left), height(x.right));   }        public Key min() {     if (isEmpty()) {       throw new NoSuchElementException("called min() with empty symbol table");     }     return min(root).key;   }    // the smallest key in subtree rooted at x; null if no such key   private Node min(Node x) {      // assert x != null;     if (x.left == null) {       return x;      }     else {       return min(x.left);      }   }       public Key max() {     if (isEmpty()) {       throw new NoSuchElementException("called max() with empty symbol table");     }     return max(root).key;   }    // the largest key in the subtree rooted at x; null if no such key   private Node max(Node x) {      // assert x != null;     if (x.right == null) {       return x;      }     else {       return max(x.right);          }   }       public Key floor(Key key) {     if (key == null) {       throw new NullPointerException("argument to floor() is null");     }     if (isEmpty()) {       throw new NoSuchElementException("called floor() with empty symbol table");     }     Node x = floor(root, key);     if (x == null) {       return null;          }     else {       return x.key;     }   }     // the largest key in the subtree rooted at x less than or equal to the given key   private Node floor(Node x, Key key) {     if (x == null) {       return null;     }     int cmp = key.compareTo(x.key);     if (cmp == 0) {       return x;     }     if (cmp < 0) {       return floor(x.left, key);          }     Node t = floor(x.right, key);     if (t != null) {       return t;          }     else {       return x;     }   }      public Key ceiling(Key key) {     if (key == null) {       throw new NullPointerException("argument to ceiling() is null");     }     if (isEmpty()) {       throw new NoSuchElementException("called ceiling() with empty symbol table");     }     Node x = ceiling(root, key);     if (x == null) {       return null;     }     else {       return x.key;      }   }   // the smallest key in the subtree rooted at x greater than or equal to the given key   private Node ceiling(Node x, Key key) {      if (x == null) {       return null;     }          int cmp = key.compareTo(x.key);     if (cmp == 0) {       return x;     }     if (cmp > 0) {       return ceiling(x.right, key);     }     Node t = ceiling(x.left, key);     if (t != null) {       return t;      }     else {       return x;     }   }      public Key select(int k) {     if (k < 0 || k >= size()) {       throw new IllegalArgumentException();     }     Node x = select(root, k);     return x.key;   }   // the key of rank k in the subtree rooted at x   private Node select(Node x, int k) {     // assert x != null;     // assert k >= 0 && k < size(x);     int t = size(x.left);      if   (t > k) {       return select(x.left, k);      }     else if (t < k) {       return select(x.right, k-t-1);      }     else {       return x;      }   }       public int rank(Key key) {     if (key == null) {       throw new NullPointerException("argument to rank() is null");     }     return rank(key, root);   }    // number of keys less than key in the subtree rooted at x   private int rank(Key key, Node x) {     if (x == null) {       return 0;      }     int cmp = key.compareTo(x.key);      if   (cmp < 0) {       return rank(key, x.left);      }     else if (cmp > 0) {       return 1 + size(x.left) + rank(key, x.right);      }     else {       return size(x.left);      }   }         public Iterable<key> keys() {     if (isEmpty()) {       return new Queue<key>();     }     return keys(min(), max());   }      public Iterable<key> keys(Key lo, Key hi) {     if (lo == null) {       throw new NullPointerException("first argument to keys() is null");     }     if (hi == null) {       throw new NullPointerException("second argument to keys() is null");     }     Queue<key> queue = new Queue<key>();     // if (isEmpty() || lo.compareTo(hi) > 0) return queue;     keys(root, queue, lo, hi);     return queue;   }    // add the keys between lo and hi in the subtree rooted at x   // to the queue   private void keys(Node x, Queue<key> queue, Key lo, Key hi) {      if (x == null) {       return;      }     int cmplo = lo.compareTo(x.key);      int cmphi = hi.compareTo(x.key);      if (cmplo < 0) {       keys(x.left, queue, lo, hi);      }     if (cmplo <= 0 && cmphi >= 0) {       queue.enqueue(x.key);      }     if (cmphi > 0) {       keys(x.right, queue, lo, hi);      }   }       public int size(Key lo, Key hi) {     if (lo == null) {       throw new NullPointerException("first argument to size() is null");     }     if (hi == null) {       throw new NullPointerException("second argument to size() is null");     }     if (lo.compareTo(hi) > 0) {       return 0;     }     if (contains(hi)) {       return rank(hi) - rank(lo) + 1;     }     else {       return rank(hi) - rank(lo);          }   }     private boolean check() {     if (!isBST())      System.out.println("Not in symmetric order");     if (!isSizeConsistent()) System.out.println("Subtree counts not consistent");     if (!isRankConsistent()) System.out.println("Ranks not consistent");     if (!is23())       System.out.println("Not a 2-3 tree");     if (!isBalanced())    System.out.println("Not balanced");     return isBST() && isSizeConsistent() && isRankConsistent() && is23() && isBalanced();   }   // does this binary tree satisfy symmetric order?   // Note: this test also ensures that data structure is a binary tree since order is strict   private boolean isBST() {     return isBST(root, null, null);   }   // is the tree rooted at x a BST with all keys strictly between min and max   // (if min or max is null, treat as empty constraint)   // Credit: Bob Dondero's elegant solution   private boolean isBST(Node x, Key min, Key max) {     if (x == null) {       return true;     }     if (min != null && x.key.compareTo(min) <= 0) {       return false;          }     if (max != null && x.key.compareTo(max) >= 0) {       return false;     }     return isBST(x.left, min, x.key) && isBST(x.right, x.key, max);   }    // are the size fields correct?   private boolean isSizeConsistent() {      return isSizeConsistent(root);    }   private boolean isSizeConsistent(Node x) {     if (x == null) {       return true;     }     if (x.size != size(x.left) + size(x.right) + 1) {       return false;     }     return isSizeConsistent(x.left) && isSizeConsistent(x.right);   }    // check that ranks are consistent   private boolean isRankConsistent() {     for (int i = 0; i < size(); i++) {       if (i != rank(select(i))) {         return false;       }     }     for (Key key : keys()) {       if (key.compareTo(select(rank(key))) != 0) {         return false;       }     }     return true;   }   // Does the tree have no red right links, and at most one (left)   // red links in a row on any path?   private boolean is23() {      return is23(root);    }   private boolean is23(Node x) {     if (x == null) {       return true;     }     if (isRed(x.right)) {       return false;     }     if (x != root && isRed(x) && isRed(x.left)){       return false;     }     return is23(x.left) && is23(x.right);   }    // do all paths from root to leaf have same number of black edges?   private boolean isBalanced() {      int black = 0;   // number of black links on path from root to min     Node x = root;     while (x != null) {       if (!isRed(x)) black++;       x = x.left;     }     return isBalanced(root, black);   }   // does every path from the root to a leaf have the given number of black links?   private boolean isBalanced(Node x, int black) {     if (x == null) {       return black == 0;          }     if (!isRed(x)) {       black--;     }     return isBalanced(x.left, black) && isBalanced(x.right, black);   }       public static void main(String[] args) {      RedBlackBST<string, integer=""> st = new RedBlackBST<string, integer="">();     String data = "a b c d e f g h m n o p";     Scanner sc = new Scanner(data);     int i = 0;     while (sc.hasNext()) {           String key = sc.next();      st.put(key, i);      i++;     }     sc.close();        for (String s : st.keys())       System.out.println(s + " " + st.get(s));     System.out.println();     boolean result = st.check();     System.out.println("check: " + result);   } }

输出:

<code>a 0b 1c 2d 3e 4f 5g 6h 7m 8n 9o 10p 11 check: true</code>

感谢你能够认真阅读完这篇文章,希望小编分享的“java算法如何实现红黑树”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网精选频道,更多相关知识等着你来学习!

--结束END--

本文标题: java算法如何实现红黑树

本文链接: https://www.lsjlt.com/news/221682.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • java算法如何实现红黑树
    这篇文章主要介绍了java算法如何实现红黑树,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。红黑树定义红黑树(英语:Red–black tree)是一种自平衡二叉查找树,是在计...
    99+
    2023-05-30
    java
  • 利用Java实现红黑树
    目录1、红黑树的属性2、旋转3、插入4、删除5、所有代码6、演示1、红黑树的属性 红黑树是一种二分查找树,与普通的二分查找树不同的一点是,红黑树的每个节点都有一个颜色(color)属...
    99+
    2022-11-12
  • java中treemap和treeset实现红黑树
    TreeMap 的实现就是红黑树数据结构,也就说是一棵自平衡的排序二叉树,这样就可以保证当需要快速检索指定节点。TreeSet 和 TreeMap 的关系为了让大家了解 TreeMap 和 TreeSet 之间的关系,下面先看 TreeSe...
    99+
    2023-05-30
    java treemap treeset
  • Java红黑树的数据结构与算法解析
    目录红黑树的介绍红黑树的实现1.节点2.查找3.平衡化颜色反转 插入的实现红黑树的复杂度–总结红黑树的介绍 红黑树(Red-Black Tree,简称R-B Tree),它一种特殊的...
    99+
    2022-11-12
  • java实现红黑树的代码怎么写
    本篇内容介绍了“java实现红黑树的代码怎么写”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 红黑树ja...
    99+
    2022-10-19
  • Java数据结构与算法系列精讲之红黑树
    目录概述红黑树红黑树的实现Node 类添加元素左旋右旋完整代码概述 从今天开始, 小白我将带大家开启 Java 数据结构 & 算法的新篇章. 红黑树 红黑树 (Red Bl...
    99+
    2022-11-13
  • Java实现红黑树(平衡二叉树)的详细过程
    目录前言红黑二叉查找树2-3树2-3树的插入操作实现红黑二叉树结尾前言 在实现红黑树之前,我们先来了解一下符号表。 符号表的描述借鉴了Algorithms第四版,详情在:https...
    99+
    2022-11-12
  • Java数据结构之红黑树的原理及实现
    目录为什么要有红黑树这种数据结构红黑树的简介红黑树的基本操作之旋转红黑树之添加元素红黑树之删除结点删除结点没有儿子的情况删除结点仅有一个儿子结点的情况删除结点有两个儿子结点红黑树动态...
    99+
    2022-11-13
  • C++ RBTree红黑树的性质与实现方法是什么
    这篇文章主要讲解了“C++ RBTree红黑树的性质与实现方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C++ RBTree红黑树的性质与实现方法是什么”吧!一...
    99+
    2023-07-05
  • Java如何实现决策树算法
    小编给大家分享一下Java如何实现决策树算法,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!具体如下:决策树算法是一种逼近离散函数值的方法。它是一种典型的分类方法,...
    99+
    2023-05-30
    java
  • 为何Redis使用跳表而非红黑树实现SortedSet
    目录什么是跳表跳表的意义究竟在于何处?跳表的搜索时间复杂度跳表是不是很费内存?插入和删除的时间复杂度插入删除跳表索引动态更新跳表的代码实现(Java 版)数据结构定义搜索算法插入和删...
    99+
    2022-11-12
  • php如何实现红包算法
    这篇文章主要介绍了 php如何实现红包算法,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。    private...
    99+
    2022-10-19
  • 利用Java如何实现一个树算法
    本篇文章为大家展示了利用Java如何实现一个树算法,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。为什么使用树:   树结合了两种数据结构的有点:一种是有序数组,树在查找数据项的速...
    99+
    2023-05-31
    java ava
  • 基于红黑树插入操作原理及java实现的示例分析
    这篇文章主要介绍基于红黑树插入操作原理及java实现的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!红黑树是一种二叉平衡查找树,每个结点上有一个存储位来表示结点的颜色,可以是RED或BLACK。红黑树具有以下...
    99+
    2023-05-30
    java
  • C#如何实现抢红包算法
    今天小编给大家分享一下C#如何实现抢红包算法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。二倍均值法(公平版) 发...
    99+
    2023-06-29
  • Java实现微信抢红包算法有哪些
    这期内容当中小编将会给大家带来有关Java实现微信抢红包算法有哪些,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。概述14年微信推出红包功能以后,很多公司开始上自己的红包功能,到现在为止仍然有很多红包开发的...
    99+
    2023-06-22
  • Java实现最小生成树算法详解
    目录定义带权图的实现Kruskal 算法二叉堆并查集实现算法Prim 算法定义 在一幅无向图G=(V,E) 中,(u,v) 为连接顶点u和顶点v的边,w(u,v)...
    99+
    2022-11-13
  • Java中关于字典树的算法实现
    字典树(前缀树)算法实现 前言 字典树,又称单词查找树,是一个典型的 一对多的字符串匹配算法。“一”指的是一个模式串,“多”指的是多个模板串。字典树经常被用来统计、排序和保存大量的字...
    99+
    2022-11-12
  • Java实现4种微信抢红包算法(小结)
    目录概述 一、剩余金额随机法 二、二倍均值法(微信红包采用此法) 三、整体随机法 四、割线法 概述 14年微信推出红包功能以后,很多公司开始上自己的红包功能,到现在为止仍然有很多红...
    99+
    2022-11-12
  • JS如何实现的二叉树算法
    这篇文章给大家分享的是有关JS如何实现的二叉树算法的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。具体如下:<!DOCTYPE HTML> <head&...
    99+
    2022-10-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作