最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

基于紅黑樹插入操作原理及java實現(xiàn)方法(分享)

 更新時間:2017年12月08日 09:48:33   作者:evasean  
下面小編就為大家分享一篇基于紅黑樹插入操作原理及java實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

紅黑樹是一種二叉平衡查找樹,每個結(jié)點上有一個存儲位來表示結(jié)點的顏色,可以是RED或BLACK。

紅黑樹具有以下性質(zhì):

(1) 每個結(jié)點是紅色或是黑色

(2) 根結(jié)點是黑色的

(3) 如果一個結(jié)點是紅色的,則它的兩個兒子都是黑色的

(4) 對于每個結(jié)點,從該結(jié)點到其子孫結(jié)點的所有路徑上包含相同數(shù)目的黑結(jié)點

通過紅黑樹的性質(zhì),可以保證所有基于紅黑樹的實現(xiàn)都能保證操作的運行時間為對數(shù)級別(范圍查找除外。它所需的額外時間和返回的鍵的數(shù)量成正比)。

Java的TreeMap就是通過紅黑樹實現(xiàn)的。

紅黑樹的操作如果不畫圖很容易搞糊涂,下面通過圖示來說明紅黑樹的插入操作。

插入一個紅色的節(jié)點到紅黑樹中之后,會有6種情況:圖示中N表示插入的節(jié)點,P表示父節(jié)點,U表示叔叔節(jié)點,G表示祖父節(jié)點,X表示當前操作節(jié)點

 

代碼如下:

public class RedBlackBST<Key extends Comparable<Key>, Value> {
 private Node root;
 private static final boolean RED = true;
 private static final boolean BLACK = false;
 private class Node{
  private Key key; //鍵
  private Value val; //值
  private Node left, right, parent; //左右子樹和父節(jié)點
  private boolean color; //由其父節(jié)點指向它的鏈接的顏色
  
  public Node(Key key, Value val,Node parent, boolean color){
   this.key = key;
   this.val = val;
   this.color = color;
  }
 }
 
 public Value get(Key key){
  Node x = root;
  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 void put(Key key, Value val){
  if(root==null) { //如果是根節(jié)點,就將節(jié)點新建為黑色
   root = new Node(key,val,null,BLACK);
   return;
  }
  //尋找合適的插入位置
  Node parent = null;
  Node cur = root;
  while(cur!=null) {
   parent = cur;
   if(key.compareTo(cur.key)>0) cur=cur.right;
   else cur = cur.left;
  }
  Node n = new Node(key,val,parent,RED); //普通的新建節(jié)點為紅色
  //將新節(jié)點插入parent下
  if(key.compareTo(parent.key) > 0) parent.right = n;
  else parent.left = n;
  //插入新節(jié)點后要調(diào)整樹中部分節(jié)點的顏色和屬性來保證紅黑樹的特征不被破壞
  fixAfterInsertion(n); 
 }
 private Node parentOf(Node x) {
  return (x==null ? null : x.parent);
 }
 private boolean colorOf(Node x) {
  return (x==null ? BLACK : x.color);
 }
 private Node leftOf(Node x) {
  return (x==null ? null : x.left);
 }
 private Node rightOf(Node x) {
  return(x==null ? null : x.right);
 }
 private void setColor(Node x, boolean color) {
  if(x!=null)
   x.color = color;
 }
 
 private void fixAfterInsertion(Node x) {
  while(x!=null && colorOf(parentOf(x)) == RED) {
   Node grandPa = parentOf(parentOf(x));
   Node parent = parentOf(x);
   if(parent == leftOf(grandPa)) {//case 1 || case2 || case3
    Node uncle = rightOf(grandPa);
    if(colorOf(uncle) == RED) {//case1, uncle is red
     setColor(parent,BLACK); //父節(jié)點置黑
     setColor(uncle, BLACK); //叔叔節(jié)點置黑
     setColor(grandPa,RED); //祖父節(jié)點置紅
     x = grandPa; //因為祖父節(jié)點由黑轉(zhuǎn)紅,故要重新調(diào)整父節(jié)點及其祖先的紅黑屬性
    }else {//case2 || case3,uncle is black
     if(x==rightOf(parent)) { //case2
      x = parent;
      rotateLeft(x);
     }
     //case3
     setColor(parent,BLACK);
     setColor(grandPa, RED);
     rotateRight(grandPa);
    }
    
   }else {//case4 || case 5 || case6
    Node uncle = leftOf(grandPa);
    if(colorOf(uncle) == RED) { //case4 || case5 || case6
     setColor(parent,BLACK);
     setColor(uncle, BLACK);
     setColor(grandPa,RED);
     x = grandPa;
    }else{ //case5 || case6, uncle is black
     if(x==leftOf(parent)) { //case5
      x = parent;
      rotateRight(x);
     }
     //case6
     setColor(parent,BLACK);
     setColor(grandPa, RED);
     rotateLeft(grandPa);
    }
   }
  }
 }
 private void rotateLeft(Node x) {
  if(x==null) return;
  Node y = x.right;
  x.right = y.left;
  if(y.left!=null)
   y.left.parent = x;
  y.left = x;
  y.parent = x.parent;
  if(x.parent == null) {
   root = y;
  }
  else if(x.parent.left == x) {
   x.parent.left = y;
  }else {
   x.parent.right = y;
  }
  x.parent = y;
 }
 private void rotateRight(Node x) {
  if(x==null) return;
  Node y = x.left;
  x.left = y.right;
  if(y.right != null)
   y.right.parent = x;
  y.right = x;
  y.parent = x.parent;
  if(x.parent == null) {
   root = y;
  }else if(x.parent.left==x) {
   x.parent.left = y;
  }else {
   x.parent.right=y;
  }
  x.parent = y;
 }
 
}

上面的rotateLeft和rotateRight有必要畫個圖示:

以上這篇基于紅黑樹插入操作原理及java實現(xiàn)方法(分享)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java實現(xiàn)短地址服務(wù)的方法(附代碼)

    java實現(xiàn)短地址服務(wù)的方法(附代碼)

    大多數(shù)情況下URL太長,字符多,不便于發(fā)布復制和存儲,本文就介紹了通過java實現(xiàn)短地址服務(wù),減少了許多使用太長URL帶來的不便,需要的朋友可以參考下
    2015-07-07
  • 詳解Mybatis中的select方法

    詳解Mybatis中的select方法

    這篇文章主要介紹了Mybatis的select方法,通過代碼給大家詳細介紹了selectByExample方法,selectById方法,需要的朋友可以參考下
    2018-07-07
  • JPA like 模糊查詢 語法格式解析

    JPA like 模糊查詢 語法格式解析

    這篇文章主要介紹了JPA like 模糊查詢 語法格式解析,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java8中時區(qū)與不同歷法處理指南

    Java8中時區(qū)與不同歷法處理指南

    Java?8?的?java.time?API?不僅修復了舊版日期時間?API?的設(shè)計缺陷,還提供了對時區(qū)和多歷法的全面支持,下面小編就來講講具體的處理操作,有需要的可以了解下
    2025-04-04
  • 淺談Mybatis之參數(shù)傳遞的幾種姿勢

    淺談Mybatis之參數(shù)傳遞的幾種姿勢

    在mybatis的日常開發(fā)中,mapper接口中定義的參數(shù)如何與xml中的參數(shù)進行映射呢?本文就詳細的介紹一下,感興趣的可以了解一下
    2021-09-09
  • springboot json時間格式化處理的方法

    springboot json時間格式化處理的方法

    這篇文章主要介紹了springboot json時間格式化處理的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03
  • java8中l(wèi)amba表達式的使用

    java8中l(wèi)amba表達式的使用

    這篇文章主要介紹了java8中l(wèi)amba表達式的使用,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-02-02
  • Java使用Apache Commons高效處理CSV文件的操作指南

    Java使用Apache Commons高效處理CSV文件的操作指南

    在 Java 開發(fā)中,CSV(Comma-Separated Values,逗號分隔值)是一種常見的數(shù)據(jù)存儲格式,廣泛用于數(shù)據(jù)交換和簡單的存儲任務(wù),本文將介紹Java使用Apache Commons高效處理CSV文件的操作指南,需要的朋友可以參考下
    2025-03-03
  • java代碼審計之目錄遍歷的解決

    java代碼審計之目錄遍歷的解決

    目錄穿越漏洞,也叫做目錄遍歷/路徑遍歷漏洞,本文主要介紹了java代碼審計之目錄遍歷的解決,文中通過案例介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-06-06
  • 了解Java線程池執(zhí)行原理

    了解Java線程池執(zhí)行原理

    那么有沒有一種辦法使得線程可以復用,就是執(zhí)行完一個任務(wù),并不被銷毀,而是可以繼續(xù)執(zhí)行其他的任務(wù)?在Java中可以通過線程池來達到這樣的效果。下面我們來詳細了解一下吧
    2019-05-05

最新評論

阿克陶县| 成都市| 宝兴县| 莱州市| 恭城| 肃宁县| 克什克腾旗| 九寨沟县| 神木县| 云和县| 集安市| 四子王旗| 乡宁县| 沁源县| 景东| 舟曲县| 富平县| 许昌市| 佳木斯市| 出国| 富民县| 桃江县| 赣榆县| 平利县| 封丘县| 马边| 达州市| 方城县| 寻甸| 宝丰县| 阿勒泰市| 京山县| 西安市| 方城县| 体育| 济宁市| 晋中市| 确山县| 桐梓县| 昌黎县| 达拉特旗|