1. 程式人生 > 其它 >樹和二叉樹

樹和二叉樹

1. 樹的基本概念

如圖所示,一棵樹最上面的點稱為根節點,如果一個節點下面連線多個節點,那麼該節點成為父節點,它下面的節點稱為子節點,一個節點可以有0個、1個或更多節點,沒有子節點的節點叫葉子節點。

1.1 二叉樹:

是一種特殊的樹,即子節點最多隻有兩個,這個限制可以使得寫出高效的插入、刪除、和查詢資料。在二叉樹中,子節點分別叫左節點和右節點。

1.2 二叉查詢樹

二叉查詢樹是一種特殊的二叉樹,相對較小的值儲存在左節點中,較大的值儲存在右節點中,這一特性使得查詢的效率很高,對於數值型和非數值型資料,比如字母和字串,都是如此。現在通過JavaScript實現一個二叉查詢樹。

1.3 實現二叉查詢樹

1.3.1 定義樹節點

二叉樹的最小元素是節點,所以先定義一個節點

// 定義節點的資料結構
function Node(data, left, right) {
    this.left = left;
    this.right = right;
    this.data = data;
    this.show = () => { return this.data }
}

1.3.2 定義二叉樹結構

// 二叉樹---建構函式
function BST() {
    this.root = null; //初始化,root為null
    this.insert = insert;  //資料插入方法
}

BST初始化時,只有一個根節點,且沒有任何資料。 接下來,我們利用二叉查詢樹的規則,定義一個插入方法,這個方法的基本思想是:

  1. 如果 BST.root === null ,那麼就將節點作為根節點
  2. 如果 BST.root !==null ,將插入節點進行一個比較,小於根節點,拿到左邊的節點,否則拿右邊,再次比較、遞迴。

這裡就出現了遞迴了,因為,總是要把較小的放在靠左的分支。

1.3.3 完善節點資料的插入

// 插入資料方法
function insert(data) {
    var node = new Node(data, null, null);
    if (this.root === null) {
        this.root = node
    } else {
        var current = this.root;
        var parent;
        while (true) {
            parent = current;
            if (data < current.data) {
                current = current.left; //到左子樹
                if (current === null) {  //如果左子樹為空,說明可以將node插入在這裡
                    parent.left = node;
                    break;  //跳出while迴圈
                }
            } else {
                current = current.right;
                if (current === null) {
                    parent.right = node;
                    break;
                }
            }
        }
    }
}

1.3.4 生成二叉樹

// 構建二叉樹
var bst = new BST();
bst.insert(10);
bst.insert(8);
bst.insert(2);
bst.insert(7);
bst.insert(5);

二叉樹結構如圖:

如何檢視資料?可能就需要使用二叉樹的遍歷

1.4 二叉樹的遍歷

  • 前序遍歷 (根左右)
  • 中序遍歷 (左根右)
  • 後序遍歷 (左右根)

例題:

JavaScript遞迴實現:

// 前序遍歷
function preOrder(node) {
    if (node !== null) {
        //如果不是null,就一直查詢左變,因此遞迴
        console.log(node.show());
        preOrder(node.left);
        preOrder(node.right);
    }
}
// 中序遍歷
function inOrder(node) {
    if (node !== null) {
        //如果不是null,就一直查詢左變,因此遞迴
        inOrder(node.left);
        //遞迴結束,列印當前值
        console.log(node.show());
        //上一次遞迴已經把左邊搞完了,右邊
        inOrder(node.right);
    }
}
// 後序遍歷
function postOrder(node) {
    if (node !== null) {
        //如果不是null,就一直查詢左變,因此遞迴
        postOrder(node.left);
        postOrder(node.right);
        console.log(node.show());
    }
}

//在剛才已有bst的基礎上執行命令
preOrder(bst.root);  // 10 8 2 7 5 
inOrder(bst.root);  // 2 5 7 8 10 
postOrder(bst.root);  //  5 7 2 8 10

1.5 二叉樹的查詢

在二叉樹這種資料結構中進行資料查詢是最方便的,現在我們就對查詢最小值、最大值和特定值進行一個梳理:

  • 最小值: 最左子樹的葉子節點
  • 最大值: 最右子樹的葉子節點
  • 特定值: targetcurrent進行比較,如果比current大,在current.right進行查詢,反之類似。

1.5.1 最大、最小值

//最小值
function getMin(bst) {
    var current = bst.root;
    while (current.left !== null) {
        current = current.left;
    }
    return current.data;
}

//最大值
function getMax(bst) {
    var current = bst.root;
    while (current.right !== null) {
        current = current.right;
    }
    return current.data;
}
console.log(getMin(bst));   // 2
console.log(getMax(bst));   // 10

1.5.2 查詢特定值

// 查詢特定值
function find(target, bst) {
    var current = bst.root;
    while (current !== null) {
        if (target === current.data) {
            return true;
        }
        else if (target > current.data) {
            current = current.right;
        } else if (target < current.data) {
            current = current.left;
        }
    }
    return -1;
}

console.log(find(9, bst));   // -1找不到
console.log(find(8, bst));   // true 在樹中

人生人山人海人來人往,自己自尊自愛自由自在。

本文來自部落格園,作者:青檸i,轉載請註明原文連結:https://www.cnblogs.com/fuct/p/15293838.html