JavaScript二叉樹深入理解

——記錄下來以便將來看看現(xiàn)在的自己

看到掘金上@MaevynZhang有篇博文講關(guān)于JS二叉樹的,寫得有點(diǎn)骨干竟贯,處女座表示看不下去了码泛! 我來自遙遠(yuǎn)的燕國,為了天下黎民澄耍,以正視聽。
??上面那位作者他直接把一個(gè)二叉樹的結(jié)構(gòu)數(shù)據(jù)生成一個(gè)二叉樹實(shí)例

QQ圖片20161208144159.jpg

這數(shù)據(jù)定的太絕了吧+_+這要要前端搬板凳吃瓜的節(jié)奏啊晌缘。吐槽截止齐莲,開始講二叉樹!
??二叉樹的一個(gè)節(jié)點(diǎn)Node由data磷箕,left选酗,right組成,data保存本節(jié)點(diǎn)的值岳枷,left指向左節(jié)點(diǎn)芒填,right指向右節(jié)點(diǎn)。二叉樹有一個(gè)<b>特殊性:相對(duì)本節(jié)點(diǎn)較小的值保存在左節(jié)點(diǎn)空繁,相對(duì)本節(jié)點(diǎn)較大的值保存在右節(jié)點(diǎn)</b>殿衰,該特性能讓查值效率提高!

創(chuàng)建Node實(shí)例
/*
* parameter: data:本節(jié)點(diǎn)的數(shù)據(jù)盛泡;left:做節(jié)點(diǎn)闷祥;right:右節(jié)點(diǎn)
*/
function Node(data,left,right){
    this.data = data;
    this.left = left;
    this.right = right;
}
function BST(){
    this.root = null;
    this.insert = insert;
}
/*
* parameter: data:本節(jié)點(diǎn)的數(shù)據(jù);
* 創(chuàng)建節(jié)點(diǎn)示例并插入到二叉樹的正確位置
*/
function Node(data,left,right){
    this.data = data;
    this.left = left;
    this.right = right;
}
function BST(){
    this.root = null;
    this.insert = insert;
}
function insert(data){
    var node = new Node(data,null,null);
    if(this.root == null){
        this.root = node;
    }else{
        var current = this.root;
        while(true){
            if(current.data > data){
                if(current.left === null){
                    current.left = node;
                    break;
                }
                current = current.left;
            }else{
                if(current.right === null){
                    current.right = node;
                    break;
                }
                current = current.right;
            }
        }
    }
}
var bst = new BST();
bst.insert(5);
bst.insert(3);
bst.insert(7);
bst.insert(2);

看代碼應(yīng)該能看出Node是怎么插入二叉樹的傲诵,下圖是代碼打印出來的樹狀結(jié)構(gòu)

Paste_Image.png

??創(chuàng)建二叉樹代碼完成凯砍,現(xiàn)在你可能高潮了,原來創(chuàng)建二叉樹這么簡單啊拴竹,那它有什么優(yōu)點(diǎn)或者缺點(diǎn)呢悟衩?二叉樹的優(yōu)點(diǎn)是查找值最快,最小值和最大值分別位于兩端栓拜,查找指定值如下:

function find(data){
    var current = this.root;
    while(true){
        if(data === current.data){
            return current;
        }
        current = data < current.data ? current.left : current.right;
        if(current === null){
            return null;
        }
    }
}

這種查找值類似二分法座泳,比列表查值快了很多惠昔,數(shù)據(jù)量越多,二叉樹比列表查值的速度就越快钳榨! (如果只是比查值效率舰罚,二分法肯定比二叉樹快,但是應(yīng)用場景不同薛耻,二分法適用在如1~100依次遞增順序列表中营罢;二叉樹可以應(yīng)用在任何數(shù)字或者字符組成的數(shù)據(jù)結(jié)構(gòu)中)。
??刪除節(jié)點(diǎn)中心思想:如果刪除節(jié)點(diǎn)是葉子節(jié)點(diǎn)饼齿,則將父節(jié)點(diǎn)指向null饲漾;如果刪除節(jié)點(diǎn)有一個(gè)子節(jié)點(diǎn),則將父節(jié)點(diǎn)指向刪除節(jié)點(diǎn)的子節(jié)點(diǎn)缕溉;如果刪除節(jié)點(diǎn)有兩個(gè)子節(jié)點(diǎn)考传,這個(gè)本文不寫,因?yàn)檫@個(gè)有點(diǎn)不合適(腦補(bǔ))证鸥!

function remove(data){
    this.root = removeNode(this.root,data);
}
function removeNode(node,data){
    if(node === null){
        return null;
    }
    if(data === node.data){
        if(node.left === null && node.right === null){
            return null;
        }
        if(node.left === null){
            return node.right;
        }
        if(node.right === null){
            return node.left;
        }
    }else if(data < node.data){
        node.left = removeNode(node.left,data);
        return node;
    }else{
        node.right = removeNode(node.right,data);
        return node;
    }
}

刪除節(jié)點(diǎn)的代碼我摘抄自《數(shù)據(jù)結(jié)構(gòu)與算法JavaScript描述》僚楞,寫得確實(shí)驚艷,感嘆代碼魅力枉层。
最后整合代碼:

function Node(data,left,right){
    this.data = data;
    this.left = left;
    this.right = right;
}
function BST(){
    this.root = null;
    this.insert = insert;
    this.find = find;
    this.remove = remove;
}
/*
* 二叉樹增加節(jié)點(diǎn)
*/
function insert(data){
    var node = new Node(data,null,null);
    if(this.root == null){
        this.root = node;
    }else{
        var current = this.root;
        while(true){
            if(current.data > data){
                if(current.left === null){
                    current.left = node;
                    break;
                }
                current = current.left;
            }else{
                if(current.right === null){
                    current.right = node;
                    break;
                }
                current = current.right;
            }
        }
    }
}
/*
* 二叉樹查節(jié)點(diǎn)
*/
function find(data){
    var current = this.root;
    while(true){
        if(data === current.data){
            return current;
        }
        current = data < current.data ? current.left : current.right;
        if(current === null){
            return null;
        }
    }
}
/*
* 二叉樹刪除節(jié)點(diǎn) (只刪除葉子節(jié)點(diǎn)泉褐、只有一個(gè)子節(jié)點(diǎn)的Node
*/
function remove(data){
    this.root = removeNode(this.root,data);
}
function removeNode(node,data){
    if(node === null){
        return null;
    }
    if(data === node.data){
        if(node.left === null && node.right === null){
            return null;
        }
        if(node.left === null){
            return node.right;
        }
        if(node.right === null){
            return node.left;
        }
    }else if(data < node.data){
        node.left = removeNode(node.left,data);
        return node;
    }else{
        node.right = removeNode(node.right,data);
        return node;
    }
}
var bst = new BST();
bst.insert(5);
bst.insert(3);
bst.insert(7);
bst.insert(2);
bst.remove(2);

二叉樹的缺點(diǎn):如果節(jié)點(diǎn)要頻繁刪除的話,不適合使用二叉樹鸟蜡,特別是被刪除的節(jié)點(diǎn)有兩個(gè)子節(jié)點(diǎn)的膜赃;
??二叉樹的優(yōu)點(diǎn):查找無規(guī)律的數(shù)字或者字母的數(shù)據(jù)結(jié)構(gòu)適合二叉樹的使用場景!

數(shù)據(jù)結(jié)構(gòu)路路漫漫揉忘,吾將上下其手跳座,老妹驚叫連連。有什么問題可以在評(píng)論區(qū)留言哦泣矛,共同進(jìn)步+_+

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末疲眷,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子乳蓄,更是在濱河造成了極大的恐慌咪橙,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件虚倒,死亡現(xiàn)場離奇詭異美侦,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)魂奥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門菠剩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人耻煤,你說我怎么就攤上這事具壮∽纪牵” “怎么了?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵棺妓,是天一觀的道長攘已。 經(jīng)常有香客問我,道長怜跑,這世上最難降的妖魔是什么样勃? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮性芬,結(jié)果婚禮上峡眶,老公的妹妹穿的比我還像新娘。我一直安慰自己植锉,他們只是感情好辫樱,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著俊庇,像睡著了一般狮暑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上辉饱,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天心例,我揣著相機(jī)與錄音,去河邊找鬼鞋囊。 笑死,一個(gè)胖子當(dāng)著我的面吹牛瞎惫,可吹牛的內(nèi)容都是我干的溜腐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼瓜喇,長吁一口氣:“原來是場噩夢啊……” “哼挺益!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起乘寒,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤望众,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后伞辛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體烂翰,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年蚤氏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了甘耿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡竿滨,死狀恐怖佳恬,靈堂內(nèi)的尸體忽然破棺而出捏境,到底是詐尸還是另有隱情,我是刑警寧澤毁葱,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布垫言,位于F島的核電站,受9級(jí)特大地震影響倾剿,放射性物質(zhì)發(fā)生泄漏筷频。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一柱告、第九天 我趴在偏房一處隱蔽的房頂上張望截驮。 院中可真熱鬧,春花似錦际度、人聲如沸葵袭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坡锡。三九已至,卻和暖如春窒所,著一層夾襖步出監(jiān)牢的瞬間鹉勒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來泰國打工吵取, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留禽额,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓皮官,卻偏偏與公主長得像脯倒,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子捺氢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容