1. 程式人生 > >javascript二叉樹

javascript二叉樹

javascript中的二叉樹一(binary tree)

  畢業也快2年了,畢業之後就沒有認真寫過部落格了,都是那裡學習一下,這裡弄一下。學習了也不做筆記,過後就忘記了。我對這種狀態打從心裡是討厭的。

  進入正題,今天的筆記是記錄javascript二叉樹的學習,是非常基本的知識加上一些自己的認識。適合想了解javascript二叉樹的萌新,大神請繞路走,當然如果發現有什麼理解上的錯誤,還望不吝賜教。

                                  ===================漂亮的分割線===================

  首先說下我對二叉樹的理解:

    1,二叉樹是由一系列有規則的節點構成

    2,二叉樹每一個節點可以看成為物件,必有key(節點值),可以有left(節點),right(節點)這三個屬性

    3,每個節點的left節點的key必定小於當前key值

    4,每個節點的right節點的key必定大於當前的key值

  那麼假如我們要把一個數組構成二叉樹,需要哪些程式碼?很簡單,記住上面的幾點,我們來一步一步把陣列變成二叉樹形式

  

  一,

    1,二叉樹是由一系列有規則的節點構成,

       2,二叉樹每一個節點可以看成為物件,必有key(節點值),可以有left(節點),right(節點)這三個屬性

    思考: 陣列的每一個值將變成二叉樹的節點(先不管這個節點怎麼排序),那麼我們在迴圈陣列的時候,是不是都要處理下?

    答: 我定義下面一個類,到時候就可以依次例項化為節點了。看下好不好理解...

//節點類
class Node {
    constructor(key) {
        this.left = null
        this.right = null
        this.key = key
    }
}

進一步解釋: 當迴圈陣列的時候,就可以把每一個數組項,例項化為節點,類似這樣new Node(陣列Item)

  二,

    3,每個節點的left節點的key必定小於當前key值

    4,每個節點的right節點的key必定大於當前的key值

    這2點是生成二叉樹的規則。那我們是不是應該有一個二叉樹類呢?

    //二叉樹類
    class BinaryTree{

    }

  思考: 二叉樹類要哪些東西呢?補充類看下是不是應該這些

//二叉樹類
class BinaryTree {
    constructor() {
        this.root = null  //二叉樹根節點
    }
    insert (key) {  //插入節點的方法
    }
}

解釋: 每一個二叉樹例項應該都有一個根節點,然後暴露一個可以插入節點的方法(先不管插入規則,後續講解)

接下來就是重點了: 如何實現插入邏輯能實現上面3,4兩點規則呢?

  第一點:我們要確定一個根節點,然後在根節點基礎上實現二分法

  完善insert方法如下:

  

class BinaryTree {
    constructor() {
        this.root = null
    }
    insert (key) {
        const newNode = new Node(key) // 這裡也可以在陣列那裡執行,但這裡可以避免多次例項操作
        if (this.root === null) {
            this.root = newNode
        } else {
            this.inOrderTraversNode(this.root, newNode)
        }
    }
    inOrderTraversNode (node, newNode) {
    }
}

解釋:當呼叫insert方法的時候都先確定root的值,然後在根節點為入口進行二分。inOrderTraversNode方法就負責二分法。

 

思考: inOrderTraversNode方法怎麼樣實現二分法?

答: 該方法為一個遞迴方法。功能為:有2個引數,一個是當前已經存在的節點,後一個是要插入的新節點,就是把新節點插入到當前節點的正確的(左節點或者右節點)位置。

比如:當根節點確定之後,呼叫該方法插入一個新左節點,此時形成了2個節點的二叉樹。此時若又一個左節點需要插入,我們就能可以遞迴呼叫該方法實現了。

//二叉樹類
class BinaryTree {
    constructor() {
        this.root = null
    }
    insert (key) {
        const newNode = new Node(key)
        if (this.root === null) {
            this.root = newNode
        } else {
            this.inOrderTraversNode(this.root, newNode)
        }
    }
    inOrderTraversNode (node, newNode) {
        if (newNode.key < node.key) { // 左插
            if (node.left === null) {
                node.left = newNode
            }else{
                this.inOrderTraversNode(node.left, newNode)
            }    
        } else { // 右插
            if (node.right === null) {
                node.right = newNode
            } else {
                this.inOrderTraversNode(node.right, newNode)
            }
        }
    }
}

 

所有程式碼在這裡,可以好好理解下

const node = [8, 1, 3, 10, 12, 6, 13, 15, 18, 7]

//節點類
class Node {
    constructor(key) {
        this.left = null
        this.right = null
        this.key = key
    }
}

//二叉樹類
class BinaryTree {
    constructor() {
        this.root = null
    }
    insert (key) {
        const newNode = new Node(key)
        if (this.root === null) {
            this.root = newNode
        } else {
            this.inOrderTraversNode(this.root, newNode)
        }
    }
    inOrderTraversNode (node, newNode) {
        if (newNode.key < node.key) { // 左插
            if (node.left === null) {
                node.left = newNode
            }else{
                this.inOrderTraversNode(node.left, newNode)
            }    
        } else { // 右插
            if (node.right === null) {
                node.right = newNode
            } else {
                this.inOrderTraversNode(node.right, newNode)
            }
        }
    }
}

const binaryTree = new BinaryTree()
node.map(function(item) {
    binaryTree.insert(item)
})

console.log(binaryTree.root)