中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript 中怎么實現一個二叉樹算法

發布時間:2021-08-07 17:38:46 來源:億速云 閱讀:160 作者:Leah 欄目:web開發

這篇文章將為大家詳細講解有關JavaScript 中怎么實現一個二叉樹算法,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

二叉樹和二叉搜索樹介紹

二叉樹中的節點最多只能有2個子節點,一個是左側子節點,一個是右側子節點,這樣定義的好處是有利于我們寫出更高效的插入,查找,刪除節點的算法。二叉搜索樹是二叉樹的一種,但是它只允許你在左側子節點存儲比父節點小的值,但在右側節點存儲比父節點大的值。接下來我們將按照這個思路去實現一個二叉搜索樹。

JavaScript 中怎么實現一個二叉樹算法

1. 創建BinarySearchTree類

這里我們將使用構造函數去創建一個類:

function BinarySearchTree(){     // 用于創建節點的類     let Node = function(key) {         this.key = key;         this.left = null;         this.right = null;     }     // 根節點     let root = null; }

我們將使用和鏈表類似的指針方式去表示節點之間的關系,如果不了解鏈表,請看我后序的文章《如何實現單向鏈表和雙向鏈表》。

2.插入一個鍵

// 插入一個鍵 this.insert = function(key) {     let newNode = new Node(key);     root === null ? (root = newNode) : (insertNode(root, newNode)) }

向樹中插入一個新的節點主要有以下三部分:1.創建新節點的Node類實例 --> 2.判斷插入操作是否為根節點,是根節點就將其指向根節點 -->  3.將節點加入非根節點的其他位置。

insertNode的具體實現如下:

function insertNode(node, newNode){     if(newNode.key < node.key) {         node.left === null ? (node.left = newNode) : (insertNode(node.left, newNode))     }else {         node.right === null ? (node.right = newNode) : (insertNode(node.right, newNode))     } }

這里我們用到遞歸,接下來要實現的search,del等都會大量使用遞歸,所以說不了解的可以先自行學習了解。我們創建一個二叉樹實例,來插入一個鍵:

let tree = new BinarySearchTree(); tree.insert(20); tree.insert(21); tree.insert(520); tree.insert(521);

插入的結構會按照二叉搜索樹的規則去插入,結構類似于上文的第一個樹圖。

樹的遍歷

訪問樹的所有節點有三種遍歷方式:中序,先序和后序。

  • 中序遍歷:以從最小到最大的順序訪問所有節點

  • 先序遍歷:以優先于后代節點的順序訪問每個節點

  • 后序遍歷:先訪問節點的后代節點再訪問節點本身

根據以上的介紹,我們可以有以下的實現代碼。

1 中序排序

this.inOrderTraverse = function(cb){     inOrderTraverseNode(root, cb); }  // 輔助函數 function inOrderTraverseNode(node, cb){     if(node !== null){         inOrderTraverseNode(node.left, cb);         cb(node.key);         inOrderTraverseNode(node.right, cb);     } }

使用中序遍歷可以實現對樹進行從小到大排序的功能。

2 先序排序

// 先序排序 --- 優先于后代節點的順序訪問每個節點    this.preOrderTraverse = function(cb) {      preOrderTraverseNode(root, cb);    }     // 先序排序輔助方法    function preOrderTraverseNode(node, cb) {      if(node !== null) {        cb(node.key);        preOrderTraverseNode(node.left, cb);        preOrderTraverseNode(node.right, cb);      }    }

使用先序排序可以實現結構化輸出的功能。

3 后序排序

// 后續遍歷 --- 先訪問后代節點,再訪問節點本身    this.postOrderTraverse = function(cb) {      postOrderTraverseNode(root, cb);    }     // 后續遍歷輔助方法    function postOrderTraverseNode(node, cb) {      if(node !== null){        postOrderTraverseNode(node.left, cb);        postOrderTraverseNode(node.right, cb);        cb(node.key);      }    }

后序遍歷可以用于計算有層級關系的所有元素的大小。

搜索樹中的值

在樹中有三種經常執行的搜索類型:最大值,最小值,特定的值。

1 最小值

最小值通過定義可以知道即是左側樹的最底端的節點,具體實現代碼如下:

// 最小值    this.min = function(){      return minNode(root)    }      function minNode(node) {      if(node) {        while(node && node.left !== null){          node = node.left;        }        return node.key      }      return null    }

相似的,實現最大值的方法如下:

// 最大值    this.max = function() {      return maxNode(root)    }     function maxNode(node) {      if(node){        while(node && node.right !== null){          node = node.right;        }        return node.key      }      return null    }

2.搜索一個特定的值

// 搜索樹中某個值 this.search = function(key) {     return searchNode(root, key) }  // 搜索輔助方法 function searchNode(node, key){     if(node === null) {         return false     }     if(key < node.key) {         return searchNode(node.left, key)     } else if(key > node.key) {         return searchNode(node.right, key)     }else {         return true     } }

3 移除一個節點

this.remove = function(key){     root = removeNode(root, key); }  // 發現最小節點 function findMinNode(node) {     if(node) {     while(node && node.left !== null){         node = node.left;     }     return node     }     return null }  // 移除節點輔助方法 function removeNode(node, key) {     if(node === null) {     return null     }      if(key < node.key){     node.left = removeNode(node.left, key);     return node     } else if( key > node.key){     node.right = removeNode(node.right, key);     return node     } else {     // 一個頁節點     if(node.left === null && node.right === null) {         node = null;         return node     }      // 只有一個子節點的節點     if(node.left === null) {         node = node.right;         return node     }else if(node.right === null) {         node = node.left;         return node     }      // 有兩個子節點的節點     let aux = findMinNode(node.right);     node.key = aux.key;     node.right = removeNode(node.right, aux.key);     return node     } }

刪除節點需要考慮的情況比較多,這里我們會使用和min類似的實現去寫一個發現最小節點的函數,當要刪除的節點有兩個子節點時,我們要將當前要刪除的節點替換為子節點中最大的一個節點的值,然后將這個子節點刪除。

關于JavaScript 中怎么實現一個二叉樹算法就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

迁西县| 仁化县| 墨脱县| 连南| 南江县| 阳春市| 公安县| 武邑县| 杂多县| 韶山市| 土默特左旗| 新沂市| 名山县| 辉南县| 惠水县| 汾西县| 芜湖县| 中江县| 商南县| 遵化市| 南京市| 怀远县| 乐陵市| 巢湖市| 鄂伦春自治旗| 镇原县| 平塘县| 平南县| 墨脱县| 长泰县| 土默特左旗| 太原市| 东源县| 昌江| 荆州市| 建阳市| 于田县| 寻乌县| 霍城县| 长顺县| 万年县|