在計算機科學中,二叉樹(英語:Binary tree)是每一個節點最多隻有兩個分支(即不存在分支度大於2的節點)的樹結構。一般分支被稱做「左子樹」或「右子樹」。二叉樹的分支具備左右次序,不能隨意顛倒。
二叉樹的第i層至多有2^{i-1}個結點;
深度爲k的二叉樹至多有2^k-1個結點;
對任何一棵二叉樹T,若樹葉總數爲 n_0,分支度爲2的總數爲n_2,則n_0=n_2+1。
一棵深度爲k,且有2^k-1個節點稱之爲滿二叉樹;
深度爲k,有n個節點的二叉樹,當且僅當其每個節點都與深度爲k的滿二叉樹中,序號爲1至n的節點對應時,稱之爲徹底二叉樹。
徹底二叉樹 | 完美二叉樹 | |
---|---|---|
總節點k | 2^ (h − 1) <= k <= 2^(h − 1) | k = 2^h − 1 |
樹高h | h = l o g 2 k + 1 | h = l o g 2 ( k + 1 ) |
英文縮寫爲DFS即Depth First Search。 在深度優先級中,咱們但願從根結點訪問最遠的結點。前序,中序和後序遍歷都是深度優先遍歷的特例。前端
先來看一張圖, 一眼瞭解這三種遍歷:node
做爲前端, 我是確定先用 JS 來實現這些遍歷的, 先定義一個二叉樹的結構:git
const nodes = { node: 6, left: { node: 5, left: { node: 4 }, right: { node: 3 } }, right: { node: 2, right: { node: 1 } } }
let list = [] function preOrder(node) { if (!(node == null)) { list.push(node.node); preOrder(node.left); preOrder(node.right); } }
執行: preOrder(nodes)
github
打印 list
結果: [6, 5, 4, 3, 2, 1]
算法
let list = [] function inOrder(node) { if (!(node == null)) { inOrder(node.left); list.push(node.node); inOrder(node.right); } }
執行: inOrder(nodes)
segmentfault
打印 list
結果: [4, 5, 3, 6, 2, 1]
app
let list = [] function postOrder(node) { if (!(node == null)) { postOrder(node.left); postOrder(node.right); list.push(node.node); } }
執行: postOrder(nodes)
post
打印 list
結果: [4, 3, 5, 1, 2, 6]
優化
英文縮寫爲BFS即Breadth FirstSearch。其過程檢驗來講是對每一層節點依次訪問,訪問完一層進入下一層,並且每一個節點只能訪問一次。 廣度遍歷即咱們尋常所說的層次遍歷。spa
const levelOrder = function (root) { if (root == null) { return [] } let result = [] let queue = [root] while (queue.length) { // 每一層的節點數 let level = queue.length let currLevel = [] // 每次遍歷一層元素 for (let i = 0; i < level; i++) { // 當前訪問的節點出隊 let curr = queue.shift() curr.left && queue.push(curr.left) curr.right && queue.push(curr.right) currLevel.push(curr.node) } result.push.apply(result, currLevel) } return result }
打印結果: [6, 5, 2, 4, 3, 1]
currLevel 中的打印: [6]
[5,2]
[4,3,1]
這個思路比較好理解, 卻是還不夠好
const levelOrder = function (root) { if (!root) return []; let queue = [root]; let res = []; while (queue.length) { let item = queue.shift(); res.push(item.node); item.left && queue.push(item.left); item.right && queue.push(item.right); } return res; }
打印結果: [6, 5, 2, 4, 3, 1]
這種算法只是用了一個隊列, 效果較好
這是二叉樹相關的第一篇, 比較基礎, 後續還會更新
倉庫地址: https://github.com/Grewer/notes
參考: