樹結(jié)構(gòu)之紅黑樹

紅黑樹是在二叉樹的基礎(chǔ)上加了紅、黑兩種顏色。

樹:

有序樹
無序樹

二叉樹:所有結(jié)點(diǎn)的度都小于等于2
前序遍歷,中序遍歷,后序遍歷,根據(jù)先訪問根的操作順序區(qū)分

翻轉(zhuǎn):

public TreeNode reverseBinaryTree(TreeNode root){
    //先處理base case,當(dāng)root ==null 時(shí),什么都不需要做,返回空指針
    if(root == null){
        return null;
    }
    else{
        //把左子樹翻轉(zhuǎn)
        TreeNode left = reverseBinaryTree(root.left);
        //把右子樹翻轉(zhuǎn)
        TreeNode right = reverseBinaryTree(root.right);
        //把左右子樹分別賦值給root節(jié)點(diǎn),但是是翻轉(zhuǎn)過來的順序
        root.left = right;
        root.right = left;
        //返回根節(jié)點(diǎn)
        return root;
    }
}

深度優(yōu)先搜索:

/**
** 二叉樹節(jié)點(diǎn)
**/
public class TreeNode{
    TreeNode left;
    TreeNode Right;
    int value;
}
//中序
public void printInoderTree(TreeNode root){
    //base case
    if(root == null){
        return;
    }
    //遞歸調(diào)用printTree
    printInoderTree(root.left);
    System.out.println(root.val);
    printInoderTree(root.right);
}
//中序
public void printPreoderTree(TreeNode root){
    //base case
    if(root == null){
        return;
    }
    //遞歸調(diào)用printTree
    System.out.println(root.val);
    printPreoderTree(root.left);
    printPreoderTree(root.right);
}

平鋪:

public TreeNode flatten(TreeNode root){  
    //base case
    if(root == null){
        return null;
    }
    else{
        //用遞歸的思想,把左右先鋪平
        TreeNode left = flatten(root.left);
        TreeNode right = flatten(root.right);
        //把左指針和右指針先指向空。
        root.left = null;
        root.right = null;
        //假如左子樹生成的鏈表為空,那么忽略它,把右子樹生成的鏈表指向根節(jié)點(diǎn)的右指針
        if(left == null){
            root.right = right;
            return root;
        }
        //如果左子樹生成鏈表不為空,那么用while循環(huán)獲取最后一個(gè)節(jié)點(diǎn),并且它的右指針要指向右子樹生成的鏈表的頭節(jié)點(diǎn)
        root.right = left;
        TreeNode lastLeft = left;
        while(lastLeft != null && lastLeft.right != null){
            lastLeft = lastLeft.right;
        }
        lastLeft.right = right;
        return root;
    }
}

廣度優(yōu)先搜索:

用隊(duì)列
public void printTree(TreeNode root){
    if(root == null){
        return;
    }
    Queue queue = new LinkedList();
    queue.add(root);
    while(!queue.isEmpty()){
        TreeNode current = queue.poll();
        System.out.println(current.toString());
        if(current.left != null){
            queue.add(current.left);
        }
        if(current.right != null){
            queue.add(current.right);
        }
    }
}

小知識(shí):集合和隊(duì)列相關(guān):
arraylist以數(shù)組實(shí)現(xiàn),但數(shù)組有容量限制,超出限制會(huì)在增加50%的容量,并用System.arraycopy()復(fù)制到新的數(shù)組
LinkedList以雙向鏈表實(shí)現(xiàn),鏈表無容量限制。但雙向鏈表使用了更多空間,也需要額外的鏈表指針操作?!倦p向鏈表實(shí)現(xiàn)的linkedList是list也是queue,他是唯一一個(gè)允許放入null的queue】
線程安全隊(duì)列:
ConcurrentLinkedQueue/ConcurrentLinkedDeque無界的并發(fā)優(yōu)化的Queue,基于鏈表,實(shí)現(xiàn)了依賴于CAS的無鎖算法。

二叉樹的next結(jié)點(diǎn):

public void nextSibiling(TreeNode node){
    if(node == null){
        return;
    }
    Queue queue = new LinkedList();
    queue.add(node);
    //這個(gè)level沒有實(shí)際用處,但是可以告訴大家怎么判斷當(dāng)前node是第幾層。
    int level = 0;
    while(!queue.isEmpty()){
        int size = queue.size();
        //用這個(gè)for循環(huán),可以保證for循環(huán)里面對(duì)queue不管加多少個(gè)子節(jié)點(diǎn),我只處理當(dāng)前層里面的節(jié)點(diǎn)
        for(int i = 0;i<size;i++){
                //把當(dāng)前第一個(gè)節(jié)點(diǎn)拿出來
                TreeNode current = queue.poll();
                //把子節(jié)點(diǎn)加到queue里面
                if(current.left != null){
                    queue.add(current.left);
                }
                if(current.right != null){
                    queue.add(current.right);
                }
                if(i != size -1){
                    //peek只是獲取當(dāng)前隊(duì)列中第一個(gè)節(jié)點(diǎn),但是并不把它從隊(duì)列中拿出來
                    current.next = queue.peek();
                }
            }
        }
        level++;
    }
}

紅黑樹

特點(diǎn):
1,根節(jié)點(diǎn)必須黑色
2,父子不能同為紅色
3,從任何一個(gè)節(jié)點(diǎn)出發(fā)到達(dá)下游葉子節(jié)點(diǎn)經(jīng)過的黑色節(jié)點(diǎn)數(shù)量一樣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一些概念 數(shù)據(jù)結(jié)構(gòu)就是研究數(shù)據(jù)的邏輯結(jié)構(gòu)和物理結(jié)構(gòu)以及它們之間相互關(guān)系,并對(duì)這種結(jié)構(gòu)定義相應(yīng)的運(yùn)算,而且確保經(jīng)過這...
    Winterfell_Z閱讀 6,574評(píng)論 0 13
  • hashmap實(shí)現(xiàn)的數(shù)據(jù)結(jié)構(gòu),數(shù)組、桶等。 如圖所示 JDK 1.7,是以數(shù)組+鏈表組成的,鏈表為相同hash的鍵...
    不需要任何閱讀 932評(píng)論 0 1
  • 動(dòng)態(tài)規(guī)劃 111. 爬樓梯思路類似斐波那契數(shù)列注意考慮第 0 階的特殊情況 272. 爬樓梯 II思路類似上題,只...
    6默默Welsh閱讀 2,600評(píng)論 0 1
  • 概述 在分析樹形結(jié)構(gòu)之前,先看一下樹形結(jié)構(gòu)在整個(gè)數(shù)據(jù)結(jié)構(gòu)中的位置 當(dāng)然,沒有圖,現(xiàn)在還沒有足夠的水平去分析圖這種太...
    wustor閱讀 2,158評(píng)論 0 3
  • 多年以后,當(dāng)我回首往事,才發(fā)覺自己的第一次艷遇竟然是在少林寺。 二零一六年三月,在寒氣尚未散盡,暖春蠢蠢欲...
    書影斜閱讀 478評(píng)論 0 0

友情鏈接更多精彩內(nèi)容