樹一種分層次的數據結構。它是由一個或者多個節點組成由層次關係的集合。之因此稱之爲樹,是由於看它外形像一顆倒掛的樹。根朝上,葉朝下。由若干個節點組成,沒有父節點的節點稱之爲根節點。一個節點只有一個父節點,一個父節點由若干個子節點。node
節點的左子節點小於父節點,節點的右子節點大於父節點。bash
function BinarySearchTree(){
// 根節點初始化
var root = null;
// 建立節點類
var Node = function(key) {
this.key = key;
this.left = null;
this.right = null;
};
// 建立節點
this.insert = function(key) {
var node = new Node(key);
if (root === null) {
root = node;
} else {
insertNode(root, node);
}
};
// 查找最小值
this.min = function() {
var node = root;
if (node) {
while (node && node.left !== null) {
node = node.left;
}
return node.key;
}
return null;
};
// 查找最大值
this.max = function() {
var node = root;
if (node) {
while (node && node.right !== null) {
node = node.right;
}
return node.key;
}
return null;
};
// 查找特定的值
this.search = function(key) {
return searchNode(root, key);
};
// 刪除指定節點
this.remove = function(key) {
root = removeNode(root, key);
};
// 中序遍歷
this.inOrderTraverse = function(callback) {
inOrderTraverseNode(root, callback);
};
// 先序遍歷
this.preOrderTraverse = function(callback) {
preOrderTraverseNode(root, callback);
};
// 後續遍歷
this.postOrderTraverse = function(callback) {
postOrderTraverseNode(root, callback);
};
// 建立節點輔助類
function insertNode(root, node) {
if (node.key < root.key) {
if (root.left === null) {
root.left = node;
} else {
insertNode(root.left, node);
}
} else {
if (root.right === null) {
root.right = node;
} else {
insertNode(root.right, node);
}
}
}
// 查找特定值輔助類
function searchNode(node, key) {
if (node) {
if (key < node.key) {
return searchNode(node.left, key);
} else if (key > node.key){
return searchNode(node.right, key);
} else {
return true;
}
} else {
return false;
}
}
// 刪除指定值輔助類
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;
}
// 第三種狀況,刪除節點有不少子節點
// 咱們須要找到刪除節點,右子節點的最小值,用最小節點去更新刪除節點
var aux = findMinNode(node.right);
node.key = aux.key;
node.right = removeNode(node.right, aux.key);
return node;
}
}
// 查找節點的最小值節點
function findMinNode(node) {
while(node && node.left) {
node = node.left;
}
return node;
}
// 中序遍歷
function inOrderTraverseNode(node, callback) {
if(node) {
inOrderTraverseNode(node.left, callback);
callback(node.key);
inOrderTraverseNode(node.right, callback);
}
}
// 先序遍歷
function preOrderTraverseNode(node, callback) {
if(node) {
callback(node.key);
preOrderTraverseNode(node.left, callback);
preOrderTraverseNode(node.right, callback);
}
}
// 後序遍歷
function postOrderTraverseNode(node, callback) {
if(node) {
preOrderTraverseNode(node.left, callback);
preOrderTraverseNode(node.right, callback);
callback(node.key);
}
}
}
var tree = new BinarySearchTree();
tree.insert(11);
tree.insert(7);
tree.insert(15);
tree.insert(5);
tree.insert(3);
tree.insert(9);
tree.insert(8);
tree.insert(10);
tree.insert(10);
tree.insert(13);
tree.insert(12);
tree.insert(14);
tree.insert(20);
tree.insert(18);
tree.insert(25);
function printNode(value) {
console.log(value);
}
// tree.inOrderTraverse(printNode);
// tree.preOrderTraverse(printNode);
// tree.postOrderTraverse(printNode);
var min = tree.min();
var max = tree.max();
var search = tree.search(7);
tree.remove(10);
tree.inOrderTraverse(printNode);
複製代碼
二叉樹結合了數據查詢的優化和鏈表插入刪除的優勢。在處理大量動態數據時很是有用。有助於更高效的對數據進行查詢、插入、刪除。數據結構
當添加的節點數,可能會出現一條邊很深的狀況。post
自平衡二叉搜索樹在進行節點的添加時,計算AVL樹的每一個節點的左子樹的hl,和右子樹的高度。若是hr-hl的差值不爲一、-一、0三者之一。則須要平衡AVL樹。這就是平衡因子。平衡AVL時,採用AVL旋轉。來處理不平衡的狀態。優化