摘要:二叉樹(shù)和二叉搜索樹(shù)二叉樹(shù)的節(jié)點(diǎn)最多只能有兩個(gè)節(jié)點(diǎn),而二叉搜索樹(shù)只允許在左側(cè)的節(jié)點(diǎn)處存儲(chǔ)比父節(jié)點(diǎn)小的值,在右側(cè)節(jié)點(diǎn)存儲(chǔ)比父節(jié)點(diǎn)大的值。接收回調(diào)函數(shù)作為參數(shù)先序遍歷先序遍歷是以優(yōu)先于后代節(jié)點(diǎn)的順序訪問(wèn)沒(méi)和節(jié)點(diǎn)的。
樹(shù)是一種非順序數(shù)據(jù)結(jié)構(gòu),對(duì)于存儲(chǔ)需要快速查找的數(shù)據(jù)非常有用。樹(shù)是一種分層數(shù)據(jù)的抽象模型,現(xiàn)實(shí)生活中最常見(jiàn)的例子就是家譜,或者是公司的組織架構(gòu)圖。
樹(shù) 樹(shù)的相關(guān)術(shù)語(yǔ)樹(shù)中的每一個(gè)元素都是節(jié)點(diǎn),節(jié)點(diǎn)分為內(nèi)部節(jié)點(diǎn)和外部節(jié)點(diǎn)。其中:
至少有一個(gè)子節(jié)點(diǎn)的節(jié)點(diǎn)稱為內(nèi)部節(jié)點(diǎn)(例如圖中節(jié)點(diǎn)7,5,9,15,13,20),沒(méi)有子元素的節(jié)點(diǎn)為外部節(jié)點(diǎn)或葉節(jié)點(diǎn)(例如圖中節(jié)點(diǎn)3,6,8,10,12,14,18,25)。
位于樹(shù)頂部的節(jié)點(diǎn)叫做根節(jié)點(diǎn),它沒(méi)有父節(jié)點(diǎn)。
節(jié)點(diǎn)的一個(gè)屬性是深度,節(jié)點(diǎn)的深度 取決于它的祖先節(jié)點(diǎn)的數(shù)量。樹(shù)的高度取決于深度的最大值。同樣一棵樹(shù)也可以分為層級(jí),根節(jié)點(diǎn)在第0層,它的子節(jié)點(diǎn)在第1層,以此類推。
二叉樹(shù)的節(jié)點(diǎn)最多只能有兩個(gè)節(jié)點(diǎn),而二叉搜索樹(shù)只允許在左側(cè)的節(jié)點(diǎn)處存儲(chǔ)(比父節(jié)點(diǎn))小的值,在右側(cè)節(jié)點(diǎn)存儲(chǔ)(比父節(jié)點(diǎn))大的值。
創(chuàng)建BinarySearchTreeconst Compare = { LESS_THAN: -1, BIGGER_THAN: 1, EQUALS: 0 }; function defaultCompare(a, b) { if (a === b) { return Compare.EQUALS; } return a < b ? Compare.LESS_THAN : Compare.BIGGER_THAN; }; class Node { constructor(key) { this.key = key; this.left = undefined; this.right = undefined; }; //下面我們會(huì)聲明BinarySearchTree類的基本骨架 class BinarySearchTree { constructor(compareFn = defaultCompare) { this.compareFn = compareFn; this.root = undefined; }向二叉搜索樹(shù)插入一個(gè)鍵
insert(key) { // special case: first key if (this.root == null) { this.root = new Node(key); } else { this.insertNode(this.root, key); } } insertNode(node, key) { if (this.compareFn(key, node.key) === Compare.LESS_THAN) { if (node.left == null) { node.left = new Node(key); } else { this.insertNode(node.left, key); } } else if (node.right == null) { node.right = new Node(key); } else { this.insertNode(node.right, key); } }樹(shù)的遍歷 中序遍歷
中序遍歷是一種以上行順序訪問(wèn)BST所有節(jié)點(diǎn)的遍歷方式,也就是從最小到最大的順序訪問(wèn)所有節(jié)點(diǎn)。中序遍歷的一種應(yīng)用是對(duì)樹(shù)進(jìn)行排序操作。
//inOrderTraverse接收回調(diào)函數(shù)作為參數(shù) inOrderTraverse(callback) { this.inOrderTraverseNode(this.root, callback); } inOrderTraverseNode(node, callback) { if (node != null) { this.inOrderTraverseNode(node.left, callback); callback(node.key); this.inOrderTraverseNode(node.right, callback); } }先序遍歷
先序遍歷是以優(yōu)先于后代節(jié)點(diǎn)的順序訪問(wèn)沒(méi)和節(jié)點(diǎn)的。先序遍歷的一種應(yīng)用是打印一個(gè)結(jié)構(gòu)化的文檔、我們來(lái)看代碼實(shí)現(xiàn)
preOrderTraverse(callback) { this.preOrderTraverseNode(this.root, callback); } preOrderTraverseNode(node, callback) { if (node != null) { callback(node.key); this.preOrderTraverseNode(node.left, callback); this.preOrderTraverseNode(node.right, callback); } }后序遍歷
后序遍歷就是縣訪問(wèn)節(jié)點(diǎn)的后代節(jié)點(diǎn),在訪問(wèn)節(jié)點(diǎn)本身。后序遍歷的一種應(yīng)用是計(jì)算一個(gè)目錄及其子目錄中所有文件所占空間的大小
postOrderTraverse(callback) { this.postOrderTraverseNode(this.root, callback); } postOrderTraverseNode(node, callback) { if (node != null) { this.postOrderTraverseNode(node.left, callback); this.postOrderTraverseNode(node.right, callback); callback(node.key); } }搜索樹(shù)中的值 搜索最小值
min() { return this.minNode(this.root); } minNode(node) { let current = node; while (current != null && current.left != null) { current = current.left; } return current; }搜索最大值
max() { return this.maxNode(this.root); } maxNode(node) { let current = node; while (current != null && current.right != null) { current = current.right; } return current; }搜索特定的值
search(key) { return this.searchNode(this.root, key); } searchNode(node, key) { if (node == null) { return false; } if (this.compareFn(key, node.key) === Compare.LESS_THAN) { return this.searchNode(node.left, key); } if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) { return this.searchNode(node.right, key); } return true; }移除節(jié)點(diǎn)
removeNode(node, key) { if (node == null) { return undefined; } if (this.compareFn(key, node.key) === Compare.LESS_THAN) { node.left = this.removeNode(node.left, key); return node; } if (this.compareFn(key, node.key) === Compare.BIGGER_THAN) { node.right = this.removeNode(node.right, key); return node; } // key is equal to node.item // handle 3 special conditions // 1 - a leaf node // 2 - a node with only 1 child // 3 - a node with 2 children // case 1 移除一個(gè)葉節(jié)點(diǎn) if (node.left == null && node.right == null) { node = undefined; return node; } // case 2 移除有一個(gè)左側(cè)或者右側(cè)子節(jié)點(diǎn)的節(jié)點(diǎn) if (node.left == null) { node = node.right; return node; } if (node.right == null) { node = node.left; return node; } // case 3 移除有兩個(gè)子節(jié)點(diǎn)的節(jié)點(diǎn) const aux = this.minNode(node.right); node.key = aux.key; node.right = this.removeNode(node.right, aux.key); return node; } }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/110039.html
摘要:二叉樹(shù)和二叉查找樹(shù)一個(gè)父節(jié)點(diǎn)的兩個(gè)子節(jié)點(diǎn)分別稱為左節(jié)點(diǎn)和右節(jié)點(diǎn)。下圖展示了一顆二叉樹(shù)當(dāng)考慮某種特殊的二叉樹(shù),比如二叉查找樹(shù)時(shí),確定子節(jié)點(diǎn)非常重要。實(shí)現(xiàn)二叉查找樹(shù)定義對(duì)象?,F(xiàn)在可以創(chuàng)建一個(gè)類來(lái)表示二叉查找樹(shù)。因此二叉查找樹(shù)也被叫做二叉排序樹(shù)。 樹(shù)是計(jì)算機(jī)科學(xué)中經(jīng)常用到的一種數(shù)據(jù)結(jié)構(gòu)。樹(shù)是一種非線性的數(shù)據(jù)結(jié)構(gòu),以分層的方式存儲(chǔ)數(shù)據(jù)。 樹(shù)被用來(lái)存儲(chǔ)具有層級(jí)關(guān)系的數(shù)據(jù),比如文件系統(tǒng)中的文件。 ...
摘要:假設(shè)一個(gè)二叉搜索樹(shù)具有如下特征節(jié)點(diǎn)的左子樹(shù)只包含小于當(dāng)前節(jié)點(diǎn)的數(shù)。所有左子樹(shù)和右子樹(shù)自身必須也是二叉搜索樹(shù)。代碼實(shí)現(xiàn)二叉樹(shù)節(jié)點(diǎn)定義來(lái)源驗(yàn)證二叉搜索樹(shù)解析 showImg(https://segmentfault.com/img/remote/1460000019005270); 這是第六周的練習(xí)題,最近加班比較多,上周主要完成一篇 GraphQL入門教程 ,有興趣的小伙伴可以看下哈。 ...
摘要:假設(shè)一個(gè)二叉搜索樹(shù)具有如下特征節(jié)點(diǎn)的左子樹(shù)只包含小于當(dāng)前節(jié)點(diǎn)的數(shù)。所有左子樹(shù)和右子樹(shù)自身必須也是二叉搜索樹(shù)。代碼實(shí)現(xiàn)二叉樹(shù)節(jié)點(diǎn)定義來(lái)源驗(yàn)證二叉搜索樹(shù)解析這是第六周的練習(xí)題,最近加班比較多,上周主要完成一篇 GraphQL入門教程 ,有興趣的小伙伴可以看下哈。 下面是之前分享的鏈接: 1.每周一練 之 數(shù)據(jù)結(jié)構(gòu)與算法(Stack) 2.每周一練 之 數(shù)據(jù)結(jié)構(gòu)與算法(LinkedList) 3...
摘要:原文博客地址學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)四樹(shù)知乎專欄簡(jiǎn)書專題前端進(jìn)擊者知乎前端進(jìn)擊者簡(jiǎn)書博主博客地址的個(gè)人博客人之所能,不能兼?zhèn)?,棄其所短,取其所長(zhǎng)。通常子樹(shù)被稱作左子樹(shù)和右子樹(shù)。敬請(qǐng)期待數(shù)據(jù)結(jié)構(gòu)篇最后一篇文章學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)五圖參考文章樹(shù)數(shù)據(jù)結(jié)構(gòu)二叉樹(shù) 前言 總括: 本文講解了數(shù)據(jù)結(jié)構(gòu)中的[樹(shù)]的概念,盡可能通俗易懂的解釋樹(shù)這種數(shù)據(jù)結(jié)構(gòu)的概念,使用javascript實(shí)現(xiàn)了樹(shù),如有紕漏,歡迎批評(píng)指正。 ...
閱讀 2276·2023-04-25 14:50
閱讀 1292·2021-10-13 09:50
閱讀 1875·2019-08-30 15:56
閱讀 1856·2019-08-29 15:29
閱讀 2897·2019-08-29 15:27
閱讀 3587·2019-08-29 15:14
閱讀 1209·2019-08-29 13:01
閱讀 3311·2019-08-26 14:06