摘要:有關(guān)算法,數(shù)據(jù)結(jié)構(gòu)的代碼已上傳至算法與數(shù)據(jù)結(jié)構(gòu)。構(gòu)造函數(shù)深度優(yōu)先遍歷廣度優(yōu)先遍歷插入中序遍歷前序遍歷后序遍歷聲明一棵樹聲明一個(gè)節(jié)點(diǎn)相關(guān)算法深度優(yōu)先遍歷深度優(yōu)先遍歷,先查看左孩子是否存在,若存在,傳入遞歸,否則,再查看右孩子。
這次來(lái)了解一下二叉樹,以及相應(yīng)的算法。以下代碼并非所有都由本人所寫,只是在此分享出來(lái),以便大家學(xué)習(xí)。
有關(guān)javascript算法,數(shù)據(jù)結(jié)構(gòu)的代碼已上傳至 javascript算法與數(shù)據(jù)結(jié)構(gòu)。
主要內(nèi)容:/** * 使用js實(shí)現(xiàn)一個(gè)二叉樹。 * Tree 構(gòu)造函數(shù) * traverseDF 深度優(yōu)先遍歷 * traverseBF 廣度優(yōu)先遍歷 * insert 插入 * inOrderTraverse中序遍歷 * preOrderTraverse前序遍歷 * postOderTraverse后序遍歷 */
聲明一棵樹:
function Tree () { this._root; }
聲明一個(gè)節(jié)點(diǎn):
function Node (data) { this.data = data; this.left = null; this.right = null; }相關(guān)算法: 深度優(yōu)先遍歷
/** * 深度優(yōu)先遍歷,先查看左孩子是否存在,若存在,傳入recurse遞歸, * 否則,再查看右孩子。若都不存在,對(duì)該節(jié)點(diǎn)執(zhí)行callback操作。 */ Tree.prototype.traverseDF = function (callback) { (function recurse (currentNode) { if (currentNode.left) { recurse(currentNode.left); } if (currentNode.right) { recurse(currentNode.right); } callback(currentNode); })(this._root) }寬度優(yōu)先遍歷
/** * 寬度優(yōu)先遍歷借助隊(duì)列來(lái)實(shí)現(xiàn)。 */ Tree.prototype.traverseBF = function (callback) { var queue = new Queue(); if (!this._root) { console.log("empty tree"); return; } queue.enqueue(this._root); var currentNode = queue.dequeue(); while (currentNode) { if (currentNode.left) { queue.enqueue(currentNode.left); } if (currentNode.right) { queue.enqueue(currentNode.right); } callback(currentNode); currentNode = queue.dequeue(); } }插入樹接節(jié)點(diǎn):
/** * 插入節(jié)點(diǎn)用到了寬度優(yōu)先遍歷的思想 */ Tree.prototype.insert = function (data) { var node = new Node(data); var message = { success: "Inserted successfully!", } if (!this._root) { this._root = node; return; } var queue = new Queue(); queue.enqueue(this._root); var currentNode = queue.dequeue(); while (currentNode) { if (currentNode.left) { queue.enqueue(currentNode.left); } else { currentNode.left = node; console.log(message.success); return; } if (currentNode.right) { queue.enqueue(currentNode.right); } else { currentNode.right = node; console.log(message.success); return; } currentNode = queue.dequeue(); } }中序遍歷:
/** * 中序遍歷 */ Tree.prototype.forInOrder = function (node) { if (node) { this.forInOrder(node.left); console.log(node.data); this.forInOrder(node.right); } } Tree.prototype.inOrderTraverse = function () { this.forInOrder(this._root); }
中序遍歷的非遞歸算法
/** * 借助一個(gè)棧,先沿著左子樹到葉節(jié)點(diǎn),依次入棧, * 再出棧遍歷,對(duì)該棧頂節(jié)點(diǎn)的右子樹進(jìn)行統(tǒng)一的操作 */ Tree.prototype.inOrder = function (callback) { var currentNode = null; if (this.root) { currentNode = root; } else { return; } var stack = []; do { while (currentNode != null) { stack.push(currentNode); currentNode = currentNode.left; } if (!stack.length) { stack.pop(currentNode); callback(currentNode); currentNode = currentNode.right; } } while (currentNode !== null && stack.length) }前序遍歷
/** * 前序遍歷 */ Tree.prototype.forPreOrder = function (node) { if (node) { console.log(node.data); this.forPreOrder(node.left); this.forPreOrder(node.right); } } Tree.prototype.preOrderTraverse = function () { this.forPreOrder(this._root); }
當(dāng)然還有前序遍歷的非遞歸算法。
/** * 算法關(guān)鍵思想是用棧為右子樹預(yù)留位置。 * 可以利用數(shù)組作為一個(gè)棧。 */ Tree.prototype.preOrder = function (callback) { var currentNode = null; if (this.root) { currentNode = this.root; } else { return; } var stack = []; while (currentNode) { callback(currentNode); if (currentNode.right) { stack.push(currentNode.right); } if (currentNode.left) { currentNode = currentNode.left; } else { currentNode = stack.pop(); } } }后序遍歷
/** * 后序遍歷 */ Tree.prototype.forPostOrder = function (node) { if (node) { this.forPostOrder(node.left); this.forPostOrder(node.right); console.log(node.data); } } Tree.prototype.postOderTraverse = function () { this.forPostOrder(this._root); }最后給出隊(duì)列的實(shí)現(xiàn)
function Queue () { this._oldestIndex = 1; this._newestIndex = 1; this._storage = {}; } Queue.prototype.enqueue = function (data) { this._storage[this._newestIndex] = data; this._newestIndex++; } Queue.prototype.dequeue = function () { var oldestIndex = this._oldestIndex, newestIndex = this._newestIndex, deletedData; if (oldestIndex !== newestIndex) { deletedData = this._storage[oldestIndex]; delete this._storage[oldestIndex]; this._oldestIndex++; return deletedData; } return null; }
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93634.html
摘要:最常被大家稱呼的兩個(gè)職位名稱是前端開發(fā)者或者前端工程師。開發(fā)者描述具有和技能的開發(fā)人員的前端職位稱呼,不要求掌握和應(yīng)用程序相關(guān)的知識(shí)。前端專家當(dāng)一詞包含在職位名稱中時(shí),這表示開發(fā)人員具有在前端技術(shù)中應(yīng)用策略的豐富經(jīng)驗(yàn)。 以下是各種前端職稱的列表和說明。最常被大家稱呼的兩個(gè)職位名稱是前端開發(fā)者或者前端工程師。請(qǐng)記住,只要是稱呼中包含前端、client-side、web UI、HTML、C...
摘要:最常被大家稱呼的兩個(gè)職位名稱是前端開發(fā)者或者前端工程師。開發(fā)者描述具有和技能的開發(fā)人員的前端職位稱呼,不要求掌握和應(yīng)用程序相關(guān)的知識(shí)。前端專家當(dāng)一詞包含在職位名稱中時(shí),這表示開發(fā)人員具有在前端技術(shù)中應(yīng)用策略的豐富經(jīng)驗(yàn)。 以下是各種前端職稱的列表和說明。最常被大家稱呼的兩個(gè)職位名稱是前端開發(fā)者或者前端工程師。請(qǐng)記住,只要是稱呼中包含前端、client-side、web UI、HTML、C...
摘要:最常被大家稱呼的兩個(gè)職位名稱是前端開發(fā)者或者前端工程師。開發(fā)者描述具有和技能的開發(fā)人員的前端職位稱呼,不要求掌握和應(yīng)用程序相關(guān)的知識(shí)。前端專家當(dāng)一詞包含在職位名稱中時(shí),這表示開發(fā)人員具有在前端技術(shù)中應(yīng)用策略的豐富經(jīng)驗(yàn)。 以下是各種前端職稱的列表和說明。最常被大家稱呼的兩個(gè)職位名稱是前端開發(fā)者或者前端工程師。請(qǐng)記住,只要是稱呼中包含前端、client-side、web UI、HTML、C...
摘要:使用來(lái)描述算法和數(shù)據(jù)結(jié)構(gòu)的教程很少,目前市面上用描述算法和數(shù)據(jù)結(jié)構(gòu)的書屈指可數(shù),并且就我看過的那本而言我只看過數(shù)據(jù)結(jié)構(gòu)與算法語(yǔ)言描述質(zhì)量實(shí)在堪憂。 使用JavaScript來(lái)描述算法和數(shù)據(jù)結(jié)構(gòu)的教程很少, 目前市面上用JS描述算法和數(shù)據(jù)結(jié)構(gòu)的書屈指可數(shù),并且就我看過的那本而言(我只看過《數(shù)據(jù)結(jié)構(gòu)與算法 JavaScript 語(yǔ)言描述》)質(zhì)量實(shí)在堪憂。碰巧有次看到Nicolas博客中的C...
閱讀 2921·2021-11-24 09:38
閱讀 3527·2021-11-23 09:51
閱讀 998·2021-09-09 11:52
閱讀 4047·2021-08-11 11:18
閱讀 1125·2019-08-30 14:05
閱讀 3239·2019-08-30 11:23
閱讀 1778·2019-08-29 17:02
閱讀 1140·2019-08-26 13:49