摘要:概念二叉樹是另一種樹型結(jié)構(gòu),它的特點是每個結(jié)點至多只有兩棵子樹即二叉樹中不存在度大于的結(jié)點,并且,二叉樹的子樹有左右之分其次序不能任意顛倒。查找最大值查找最小值思路傳入二叉樹,尋找左子樹,直到找到不存在左子樹的節(jié)點。
概念
二叉樹(Binary Tree)是另一種樹型結(jié)構(gòu),它的特點是每個結(jié)點至多只有兩棵子樹(即二叉樹中不存在度大于 2 的結(jié)點),并且,二叉樹的子樹有左右之分(其次序不能任意顛倒。)
性質(zhì)二叉樹的第 i 層上最多有 2 的(i-1)方個節(jié)點。(i>=1)
深度為 k 的樹最多有 2 的 k 次方-1 個節(jié)點。(k>=1)
對任何一棵二叉樹 T,如果其終端結(jié)點數(shù)為 n0,度為 2 的結(jié)點數(shù)為 n2,則 n0 = n2 + 1;
_ 一棵深度為 k 且有 2 的 k 次方-1 個結(jié)點的二叉樹稱為滿二叉樹。
_ 深度為 k 的,有 n 個結(jié)點的二叉樹,當(dāng)且僅當(dāng)其每一個結(jié)點都與深度為 k 的滿二叉樹中編號從 1 至 n 的結(jié)點一一對應(yīng)時,稱之為完全二叉樹。
// 創(chuàng)建節(jié)點 class Node { constructor(key) { this.key = key this.left = null this.right = null } }
// 創(chuàng)建二叉樹格式 class BinaryTree { constructor(...args) { this.root = null // 初始化依次插入數(shù)據(jù) args.forEach(key => { this.insert(key) }) } // 實例化 static create(args) { return new BinaryTree(...args) } }新增方法
思路:判斷插入的節(jié)點和當(dāng)前節(jié)點,若大于當(dāng)前節(jié)點,去右子樹插入,否則左子樹插入。
insert(key) { const newNode = new Node(key); const insertNode = function(node, newNode) { if (newNode.key < node.key) { // 如果新節(jié)點的值小于老節(jié)點的值 if (node.left === null) { // 如果老節(jié)點沒有左孩子 node.left = newNode; } else { // 如果老節(jié)點有左孩子,那么講數(shù)據(jù)插入到老節(jié)點的左孩子 insertNode(node.left, newNode); } } else { // 如果新節(jié)點的值大于老節(jié)點 if (node.right === null) { node.right = newNode; } else { insertNode(node.right, newNode); } } }; if (this.root === null) { // 如果root不存在,將newNode設(shè)為根節(jié)點 this.root = newNode } else { insertNode(this.root, newNode) } }
調(diào)用形式
const nodes = [8, 3, 10, 1, 6, 14, 4, 7, 13] const binaryTree = BinaryTree.create(nodes) binaryTree.insert(55) console.log(binaryTree.root)遍歷方法
二叉樹的遍歷(traversing binary tree)是指從根結(jié)點出發(fā),按照某種次序依次訪問二叉樹中所有結(jié)點,使得每個結(jié)點被訪問一次且僅被訪問一次。
前序遍歷(DLR)首先訪問根結(jié)點,然后遍歷左子樹,最后遍歷右子樹。簡記根-左-右。
用途:用于復(fù)制一顆二叉樹
算法思路
若二叉樹為空,則遍歷結(jié)束;否則 1. 訪問根結(jié)點 2. 先序遍歷左子樹(遞歸調(diào)用本算法) 3. 先序遍歷右子樹(遞歸調(diào)用本算法)
// 前序遍歷 preOrderTraverse () { const preOrderTraverse = node => { if (node !== null) { console.log(node.key) preOrderTraverse(node.left) preOrderTraverse(node.right) } } preOrderTraverse(this.root) }中序遍歷(LDR)
首先遍歷左子樹,然后訪問根結(jié)點,最后遍歷右子樹。簡記左-根-右。
用途:用于從小到大排序二叉樹
算法思路
若二叉樹為空,則遍歷結(jié)束;否則 1. 中序遍歷左子樹(遞歸調(diào)用本算法) 2. 訪問根結(jié)點 3. 中序遍歷右子樹(遞歸調(diào)用本算法)
//使用遞歸方式實現(xiàn)中序遍歷 inOrderTraverse () { const inOrderTraverseNode = node => { if (node !== null) { // 如果當(dāng)前節(jié)點非空,則訪問左子樹 inOrderTraverseNode(node.left) // 直到訪問到最底部的左子樹才進(jìn)入callback,每個節(jié)點都會有callback console.log(node.key) // 此時已經(jīng)是最底部的左子樹 inOrderTraverseNode(node.right) } // 解釋:首先進(jìn)入8,發(fā)現(xiàn)左邊有3,執(zhí)行左邊遍歷,遍歷完后執(zhí)行3的回調(diào),在執(zhí)行3的右邊的回調(diào), } inOrderTraverseNode(this.root) }后序遍歷(LRD)
首先遍歷左子樹,然后遍歷右子樹,最后訪問根結(jié)點。簡記左-右-根。
算法思路
若二叉樹為空,則遍歷結(jié)束;否則 1. 后序遍歷左子樹(遞歸調(diào)用本算法); 2. 后序遍歷右子樹(遞歸調(diào)用本算法) ; 3. 訪問根結(jié)點 。
postOrderTraverse () { const postOrderTraverse = node => { if (node !== null) { postOrderTraverse(node.left) postOrderTraverse(node.right) console.log(node.key) } } postOrderTraverse(this.root) }查找算法 查找最大值
思路:傳入二叉樹,尋找右子樹,直到找到不存在右子樹的節(jié)點。
// 查找最大值 max () { const maxNode = node => { if (node !== null) { if (node.right) { return maxNode(node.right) } else { return node.key } } } return maxNode(this.root) }查找最小值
思路:傳入二叉樹,尋找左子樹,直到找到不存在左子樹的節(jié)點。
// 查找最小值 min () { const minNode = node => { if (node !== null) { if (node.left) { return minNode(node.left) } else { return node.key } } } return minNode(this.root) }查找任意值
思路:根據(jù)傳入的 key 與當(dāng)前節(jié)點比較,如果大于當(dāng)前 key 則去右子樹查找,否則去左子樹查找。
// 查找指定值 search (key) { const searchNode = function(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 } } return searchNode(this.root, key) }刪除算法
思路:如果刪除的 key 小于當(dāng)前節(jié)點,去左子樹種查找,否則去右子樹查找。找到節(jié)點后,判斷是否存在子節(jié)點,若不存在,直接刪除,若只存在左節(jié)點或者右節(jié)點,將當(dāng)前節(jié)點替換為它的子節(jié)點。若左右節(jié)點都存在,將右節(jié)點中的最小值(左子樹)移除并替換為刪除的節(jié)點位置(為了滿足二叉樹的左子樹小于右子樹)
remove (key) { // 用于查找最小節(jié)點 const findMinNode = node => { if (node) { // 如果node的左孩子存在 while (node && node.left !== null) { // 將node設(shè)為node的左孩子再次進(jìn)入循環(huán) node = node.left } // 直到返回沒有左孩子的node return node } } const removeNode = (node, key) => { if (node === null) { return false } if (key < node.key) { // 當(dāng)前node大于刪除key,去左孩子中查找 node.left = removeNode(node.left, key) return node } else if (key > node.key) { // 當(dāng)前node小于刪除key,去右孩子中查找 node.right = removeNode(node.right, key) } else { // key和當(dāng)前node相等 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 } // 同時存在左孩子和右孩子 // 找出右邊的最小值 const aux = findMinNode(node.right) // 將最小值替換為刪除的key node.key = aux.key // 在右孩子中刪除最小值 node.right = removeNode(node.right, aux.key) return node } } const result = removeNode(this.root, key) console.log(result) }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/95618.html
摘要:當(dāng)集合為空時,稱該二叉樹為空二叉樹。也就是說,如果一個二叉樹的層數(shù)為,且結(jié)點總數(shù)是,則它就是滿二叉樹。完全二叉樹完全二叉樹是效率很高的數(shù)據(jù)結(jié)構(gòu),完全二叉樹是由滿二叉樹而引出來的。 ...
摘要:本篇主要介紹二叉樹的概念二叉樹的表示二叉樹的操作三種遍歷方式實現(xiàn)求二叉樹的子樹求節(jié)點的父節(jié)點二叉樹高度,可能是考試中的,也可能是面試中的。通常二叉樹的遍歷根據(jù)根節(jié)點的遍歷次序分為先根遍歷中根遍歷后根遍歷。 聲明:碼字不易,轉(zhuǎn)載請注明出處,歡迎文章下方討論交流。 前言:Java數(shù)據(jù)結(jié)構(gòu)與算法專題會不定時更新,歡迎各位讀者監(jiān)督。本篇主要介紹二叉樹的概念、二叉樹的表示、二叉樹的操作(三種遍歷...
摘要:代碼實現(xiàn)如下二叉樹的創(chuàng)建與銷毀二叉樹的創(chuàng)建問題通過前序遍歷的數(shù)組給定一串字符串,代表的是空樹,其他的都是節(jié)點。 ??本篇博客我要來和大家一起聊一聊數(shù)據(jù)結(jié)構(gòu)中的二...
摘要:樹中結(jié)點的最大層次稱為樹的深度或高度。二叉樹有深度遍歷和廣度遍歷,深度遍歷有前序中序和后序三種遍歷方法。二叉樹的前序遍歷可以用來顯示目錄結(jié)構(gòu)等中序遍歷可以實現(xiàn)表達(dá)式樹,在編譯器底層很有用后序遍歷可以用來實現(xiàn)計算目錄內(nèi)的文件及其信息等。 樹的簡介 棧、隊列、鏈表等數(shù)據(jù)結(jié)構(gòu),都是順序數(shù)據(jù)結(jié)構(gòu)。而樹是非順序數(shù)據(jù)結(jié)構(gòu)。樹型結(jié)構(gòu)是一類非常重要的非線性結(jié)構(gòu)。直觀地,樹型結(jié)構(gòu)是以分支關(guān)系定義的層次結(jié)...
摘要:同樣結(jié)點樹的二叉樹,完全二叉樹的深度最小。二叉樹每個結(jié)點最多有兩個孩子,所以為它設(shè)計一個數(shù)據(jù)域和兩個指針域是比較自然的想法,我們稱這樣的鏈表叫做二叉鏈表。 二叉樹的概念 二叉樹(Binary Tree)是n(n>=0)個結(jié)點的有限集合,該集合或者為空集(空二叉樹),或者由一個根結(jié)點和兩棵互不相交的、分別稱為根結(jié)點的左子樹和右子樹的二叉樹組成。 showImg(https://seg...
閱讀 1909·2021-11-25 09:43
閱讀 1556·2021-09-02 15:21
閱讀 3522·2019-08-30 15:52
閱讀 1557·2019-08-30 12:48
閱讀 1372·2019-08-30 10:57
閱讀 2989·2019-08-26 17:41
閱讀 741·2019-08-26 11:59
閱讀 1427·2019-08-26 10:41