成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

通過幾道題目學(xué)習(xí)二叉搜索樹

Steven / 758人閱讀

摘要:根據(jù)這個(gè)特征,用二分法來將有序數(shù)組轉(zhuǎn)換為一顆二叉搜索樹。邊界條件向下取整得到中間值遞歸二分法接下來我們驗(yàn)證下一棵樹是否滿足二叉搜索樹。二驗(yàn)證二叉搜索樹相關(guān)題目驗(yàn)證二叉搜索樹中等思路就是,中序遍歷如果滿足遞增的就行。

二叉樹大家都知道,二叉搜索樹滿足以下特征:

節(jié)點(diǎn)的左子樹只包含小于當(dāng)前節(jié)點(diǎn)的數(shù)

節(jié)點(diǎn)的右子樹只包含大于當(dāng)前節(jié)點(diǎn)的數(shù)

所有左子樹和右子樹自身必須也是二叉搜索樹

二叉搜索樹也叫二叉排序樹,中序遍歷二叉搜索樹的結(jié)果就是一次遞增的遍歷。 一、二叉搜索樹的建立

相關(guān)題目:leetcode 108.將有序數(shù)組轉(zhuǎn)換為二叉搜索樹 [中等]

那么如何將一個(gè)有序數(shù)組轉(zhuǎn)換為一顆二叉搜索樹?

二叉搜索樹的每一個(gè)分支的根節(jié)點(diǎn)都是他的中間值。根據(jù)這個(gè)特征,用二分法來將有序數(shù)組轉(zhuǎn)換為一顆二叉搜索樹。

const sortedArrayToBST = nums => {
    // 邊界條件
    if (nums.length === 0) {
        return null;
    } 
    if (nums.length === 1) {
        return new TreeNode(nums[0]);
    }
    // 向下取整得到中間值
    let mid = Math.floor(nums.length / 2);
    let root = new TreeNode(nums[mid]);
    // 遞歸 二分法
    root.left =  sortedArrayToBST(nums.slice(0, mid));
    root.right =  sortedArrayToBST(nums.slice(mid + 1));
    return root;
};

接下來我們驗(yàn)證下一棵樹是否滿足二叉搜索樹。

二、驗(yàn)證二叉搜索樹

相關(guān)題目:leetcode 98.驗(yàn)證二叉搜索樹 [中等]

思路就是,中序遍歷如果滿足遞增的就行。

用一個(gè)max作為驗(yàn)證值的變量,用中序遍歷前面的值和后面的值作比較,一直遞增則滿足二叉搜索樹。

const isValidBST = root => {
    let isValidBSTFlag = true;
    let max = -Number.MAX_VALUE;
    const orderSearch = root => {
        if (root) {
            orderSearch(root.left);
            if (root.val > max) {
                max = root.val;
            } else {
                isValidBSTFlag = false;
            }
            orderSearch(root.right);
        }
    }
    orderSearch(root);
    return isValidBSTFlag;
};

上一個(gè)非遞歸解法。

非遞歸中序遍歷的思路就是使用棧,將節(jié)點(diǎn)的左子樹壓入直到葉節(jié)點(diǎn),然后操作完左子樹跟根節(jié)點(diǎn)后再操作右子樹。

循環(huán)反復(fù),直到???。

const isValidBST = root => {
    if(!root) return true;
    let stack = [];
    let isValidBSTFlag = true;
    let max = -Number.MAX_VALUE;
    while (1) {
        while(root != null){
            stack.push(root);
            root = root.left;
        }
        if (stack.length === 0) break;
        let node = stack.pop();
        if (node.val > max) {
            max = node.val;
        } else {
            isValidBSTFlag = false;
            break;
        }
        root = node.right;
    }
    return isValidBSTFlag;
}
三、二叉搜索樹的插入

相關(guān)題目:leetcode 701.二叉搜索樹中的插入操作 [中等]

將值插入二叉搜索樹,只要樹在插入后仍保持為二叉搜索樹即可。

思路:找到大于插入節(jié)點(diǎn)值的節(jié)點(diǎn),將要插入的節(jié)點(diǎn)作為該節(jié)點(diǎn)的左子樹。注意細(xì)節(jié)。

這里還是用中序遍歷,中序遍歷能很好地解決一種情況,就是要插入的節(jié)點(diǎn)值比樹中的所有節(jié)點(diǎn)還大。

這種情況,找到樹中最大值的節(jié)點(diǎn),將插入的節(jié)點(diǎn)作為該節(jié)點(diǎn)的右節(jié)點(diǎn)。

沒用遞歸,方便理解。

const insertIntoBST = (root, val) => {
    let stack = [];
    let r = root;
    let node = null;
    while (1) {
        while(root != null) {
            stack.push(root);
            root = root.left;
        }
        if (stack.length === 0) break;
        node = stack.pop();
        // 找到大于插入節(jié)點(diǎn)值的節(jié)點(diǎn)
        if (node.val > val) {
            let newNode = new TreeNode(val);
            newNode.left = node.left;
            // 這里是細(xì)節(jié)
            node.left = newNode;
            break;
        }
        root = node.right;
    }
    // 要插入的節(jié)點(diǎn)值比樹中的所有節(jié)點(diǎn)還大
    if (val > node.val) {
        node.right = new TreeNode(val);
    }
    return r;
};
四、二叉搜索樹的恢復(fù)

相關(guān)題目:leetcode 99.恢復(fù)二叉搜索樹 [困難]

要求:二叉搜索樹中的兩個(gè)節(jié)點(diǎn)被錯(cuò)誤地交換。請(qǐng)?jiān)诓桓淖兤浣Y(jié)構(gòu)的情況下,恢復(fù)這棵樹。

思路:利用中序遍歷找到錯(cuò)誤的兩個(gè)節(jié)點(diǎn)s1,s2。交換這兩個(gè)節(jié)點(diǎn)。

用一個(gè)數(shù)組保存遍歷的值,如果前一個(gè)節(jié)點(diǎn)大于后一個(gè)節(jié)點(diǎn),則s1肯定是前一個(gè)節(jié)點(diǎn),后一個(gè)節(jié)點(diǎn)不一定是s2,繼續(xù)遍歷尋找找到s2。

const recoverTree = root => {
    let res = [];
    let s1 = s2 = null;
    const orderSearch = root => {
        if (root) {
            orderSearch(root.left);
            if (res.length !== 0) {
                if (res[res.length - 1].val > root.val) {
                    // 第一個(gè)找到的才是s1
                    !s1 && (s1 = res[res.length - 1]);
                    // 若有第二次,第二次的才是s2
                    s2 = root;
                }
            }
            
            res.push(root)
            orderSearch(root.right);
        }
    }
    orderSearch(root);
    [s1.val, s2.val] = [s2.val, s1.val];
    return root;
};
總結(jié):

二叉搜索樹跟排序相關(guān),總是圍繞著中序遍歷進(jìn)行操作。

遞歸代碼簡潔但是不好理解,非遞歸相對(duì)容易理解一些,兩者效率差不太大,看場景使用。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99424.html

相關(guān)文章

  • 幾道Java集合框架面試題在面試中幾乎必問

    摘要:若遇到哈希沖突,則將沖突的值加到鏈表中即可。之后相比于之前的版本,之后在解決哈希沖突時(shí)有了較大的變化,當(dāng)鏈表長度大于閾值默認(rèn)為時(shí),將鏈表轉(zhuǎn)化為紅黑樹,以減少搜索時(shí)間。有序,唯一紅黑樹自平衡的排序二叉樹。 本文是最最最常見Java面試題總結(jié)系列第三周的文章。主要內(nèi)容: Arraylist 與 LinkedList 異同 ArrayList 與 Vector 區(qū)別 HashMap的底層...

    bigdevil_s 評(píng)論0 收藏0
  • ?算法入門?《二叉 - 二叉搜索》簡單05 —— LeetCode 897. 遞增順序搜索

    文章目錄 一、題目1、題目描述2、基礎(chǔ)框架3、原題鏈接 二、解題報(bào)告1、思路分析2、時(shí)間復(fù)雜度3、代碼詳解 三、本題小知識(shí)四、加群須知 一、題目 1、題目描述 ??給你一棵二叉搜索樹,請(qǐng)按 中序遍歷 將其重新排列為一棵遞增順序搜索樹,使樹中最左邊的節(jié)點(diǎn)成為樹的根節(jié)點(diǎn),并且每個(gè)節(jié)點(diǎn)沒有左子節(jié)點(diǎn),只有一個(gè)右子節(jié)點(diǎn)。??樣例輸入: [5,3,6,2,4,null,8,1,null,null,nu...

    Soarkey 評(píng)論0 收藏0
  • 學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(四):二叉搜索

    摘要:像剛才的這幅圖,就是二叉搜索樹。而我們本文要學(xué)習(xí)的內(nèi)容,就是如何寫一個(gè)二叉搜索樹。但在二叉搜索樹中,我們把節(jié)點(diǎn)成為鍵,這是術(shù)語。前端路漫漫,且行且歌的前端樂園原文鏈接寒假前端學(xué)習(xí)學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)與算法四二叉搜索樹 本系列的第一篇文章: 學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(一),棧與隊(duì)列第二篇文章:學(xué)習(xí)JavaScript數(shù)據(jù)結(jié)構(gòu)與算法(二):鏈表第三篇文章:學(xué)習(xí)JavaScript數(shù)據(jù)...

    ingood 評(píng)論0 收藏0
  • PHPer面試必看:分門別類帶你擼《劍指Offer》之二叉

    摘要:例如輸入前序遍歷序列和中序遍歷序列,則重建二叉樹并返回。操作給定的二叉樹,將其變換為源二叉樹的鏡像。劍指中還有一道類似的變種題目,就是下面的這道,之字形遍歷二叉樹。最后下面的兩道題目分別運(yùn)用了二叉樹先序中序遍歷算法。 開篇 以下內(nèi)容可能偏應(yīng)試但很好理解,所以大家一定要堅(jiān)持看下去,因?yàn)槲覀冏儚?qiáng)的過程注定孤獨(dú)的,堅(jiān)持下來就會(huì)看到明天的太陽。 回顧 showImg(https://user-...

    li21 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<