Dieser Artikel vermittelt Ihnen relevantes Wissen über Javascript. Er stellt hauptsächlich die Details von JavaScript-Binärbäumen und verschiedenen Traversal-Algorithmen vor, die einen gewissen Referenzwert haben . Ich hoffe, es hilft allen.
[Verwandte Empfehlungen: Javascript-Video-Tutorial, Web-Frontend]
Ein Binärbaum ist ein Baum, in dem jeder Knoten höchstens zwei untergeordnete Knoten haben kann , wie in der folgenden Abbildung gezeigt:
Ein Binärbaum hat die folgenden Eigenschaften:
i
-te Schicht hat höchstens nur 2^(i- 1)
Knoten; i
层的节点最有只有2^(i-1)
个;k
,那二叉树最多有2^k-1
个节点;n0
表示叶子节点的个数,n2
是度为2的非叶子节点的个数,那么两者满足关系n0 = n2 + 1
。如果在一个二叉树中,除了叶子节点,其余的节点的每个度都是2,则说明该二叉树是一个满二叉树,
如下图所示:
满二叉树除了满足普通二叉树特质,还具有如下几个特质:
n
层具有2^(n-1)
个节点;k
的满二叉树一定存在2^k-1
个节点,叶子节点的个数为2^(k-1)
;n
个节点的满二叉树的深度为log_2^(n+1)
。如果一个二叉树去掉最后一次层是满二叉树,且最后一次的节点是依次从左到右分布的,则这个二叉树是一个完全二叉树,
如下图所示:
存储二叉树的常见方式分为两种,一种是使用数组存储,另一种使用链表存储。
使用数组存储二叉树,如果遇到完全二叉树,存储顺序从上到下,从左到右,如下图所示:
如果是一个非完全二叉树,如下图所示:
需要先将其转换为完全二叉树,然后在进行存储,如下图所示:
可以很明显的看到存储空间的浪费。
使用链表存储通常将二叉树中的分为3个部分,如下图:
这三个部分依次是左子树的引用,该节点包含的数据,右子树的引用,存储方式如下图所示:
以下算法中遍历用到的树如下:
// tree.js const bt = { val: 'A', left: { val: 'B', left: { val: 'D', left: null, right: null }, right: { val: 'E', left: null, right: null }, }, right: { val: 'C', left: { val: 'F', left: { val: 'H', left: null, right: null }, right: { val: 'I', left: null, right: null }, }, right: { val: 'G', left: null, right: null }, }, } module.exports = bt
二叉树的深度优先遍历与树的深度优先遍历思路一致,思路如下:
left
right
实现代码如下:
const bt = { val: 'A', left: { val: 'B', left: { val: 'D', left: null, right: null }, right: { val: 'E', left: null, right: null }, }, right: { val: 'C', left: { val: 'F', left: { val: 'H', left: null, right: null }, right: { val: 'I', left: null, right: null }, }, right: { val: 'G', left: null, right: null }, }, } function dfs(root) { if (!root) return console.log(root.val) root.left && dfs(root.left) root.right && dfs(root.right) } dfs(bt) /** 结果 A B D E C F H I G */
实现思路如下:
left
和right
k
beträgt, dann hat der Binärbaum höchstens 2^k-1
Knoten Wenn in einem nicht leeren Binärbaum n0
die Anzahl der Blattknoten darstellt und n2
die Anzahl der Nicht-Blattknoten mit Grad 2 ist, erfüllen die beiden die Anforderungen die Beziehung n0 = n2 + 1
. Vollständiger Binärbaum
Wenn in einem BinärbaumWie in der Abbildung gezeigt Abbildung unten:
🎜🎜n
te Ebene eines vollständigen Binärbaums hat 2^(n-1)</code > Knoten; 🎜🎜Die Tiefe beträgt <code>k<. Der vollständige Binärbaum von /code> muss <code>2^k-1
Knoten haben und die Anzahl der Blattknoten beträgt 2^( k-1)
; 🎜🎜hat Die Tiefe eines vollständigen Binärbaums mit n
Knoten beträgt log_2^(n+1)
. 🎜🎜🎜Vollständiger Binärbaum🎜🎜🎜Wenn ein Binärbaum nach dem Entfernen der letzten Ebene ein vollständiger Binärbaum ist und der letzte Knoten 🎜von links nach rechts verteilt ist, dann ist der Binärbaum ein vollständiger Binärbaum, 🎜🎜🎜wie Wie in der folgenden Abbildung gezeigt: 🎜🎜🎜function bfs(root) { if (!root) return const queue = [root] while (queue.length) { const node = queue.shift() console.log(node.val) node.left && queue.push(node.left) node.right && queue.push(node.right) } } bfs(bt) /** 结果 A B C D E F G H I */
des Wurzelknotens
🎜🎜Zugreifen Sie auf den Rechts
der Wurzel Knoten🎜🎜 Wiederholen Sie den zweiten und dritten Schritt zur Warteschlange🎜🎜Entfernen Sie den Gegner aus der Warteschlange und greifen Sie darauf zu🎜🎜Geben Sie nacheinander links
und rechts
an der Spitze der Warteschlange ein🎜🎜Wiederholen Sie die Schritte 2 und 3, bis die Warteschlange ist leer🎜🎜🎜🎜Der Implementierungscode lautet wie folgt:🎜🎜const bt = require('./tree') function preorder(root) { if (!root) return console.log(root.val) preorder(root.left) preorder(root.right) } preorder(bt) /** 结果 A B D E C F H I G */
如下图所示:
递归方式实现如下:
const bt = require('./tree') function preorder(root) { if (!root) return console.log(root.val) preorder(root.left) preorder(root.right) } preorder(bt) /** 结果 A B D E C F H I G */
迭代方式实现如下:
// 非递归版 function preorder(root) { if (!root) return // 定义一个栈,用于存储数据 const stack = [root] while (stack.length) { const node = stack.pop() console.log(node.val) /* 由于栈存在先入后出的特性,所以需要先入右子树才能保证先出左子树 */ node.right && stack.push(node.right) node.left && stack.push(node.left) } } preorder(bt) /** 结果 A B D E C F H I G */
二叉树的中序遍历实现思想如下:
如下图所示:
递归方式实现如下:
const bt = require('./tree') // 递归版 function inorder(root) { if (!root) return inorder(root.left) console.log(root.val) inorder(root.right) } inorder(bt) /** 结果 D B E A H F I C G */
迭代方式实现如下:
// 非递归版 function inorder(root) { if (!root) return const stack = [] // 定义一个指针 let p = root // 如果栈中有数据或者p不是null,则继续遍历 while (stack.length || p) { // 如果p存在则一致将p入栈并移动指针 while (p) { // 将 p 入栈,并以移动指针 stack.push(p) p = p.left } const node = stack.pop() console.log(node.val) p = node.right } } inorder(bt) /** 结果 D B E A H F I C G */
二叉树的后序遍历实现思想如下:
如下图所示:
递归方式实现如下:
const bt = require('./tree') // 递归版 function postorder(root) { if (!root) return postorder(root.left) postorder(root.right) console.log(root.val) } postorder(bt) /** 结果 D E B H I F G C A */
迭代方式实现如下:
// 非递归版 function postorder(root) { if (!root) return const outputStack = [] const stack = [root] while (stack.length) { const node = stack.pop() outputStack.push(node) // 这里先入left需要保证left后出,在stack中后出,就是在outputStack栈中先出 node.left && stack.push(node.left) node.right && stack.push(node.right) } while (outputStack.length) { const node = outputStack.pop() console.log(node.val) } } postorder(bt) /** 结果 D E B H I F G C A */
【相关推荐:javascript视频教程、web前端】
Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in JavaScript-Binärbäume und verschiedene Traversalalgorithmen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!