把第一位當作根節點,比根節點小的數放在左子樹上,比根節點大的數放到右子樹上,以此類推。javascript
把下面數組生成一個二叉樹:let nodes = [8,3,6,4,9,11,2,5,7];
java
結構以下
node
生成的二叉樹對象以下數組
let tree = {
key: 8,
left: {
key: 3,
left: {
key: 2,
left: null,
right: null
},
right: {
key: 6,
left: {
key: 4,
left: null,
right: {
key: 5,
left: null,
right: null
}
},
right: {
key: 7,
left: null,
right: null
}
}
}
right: {
key: 9,
left: null,
right: {
key: 11,
left: null,
right: null
}
}
}複製代碼
//API:
//insert添加一個子樹,傳值Number
//bulkInsert批量添加子樹,傳值Array
//showTree返回二叉樹對象
class BinaryTree {
constructor(tree = []) {
this.root = null;//樹根
this.Node = key => {
//生成一個新的子樹
let _obj = Object.create(null, {});
_obj.key = key;
_obj.left = null;
_obj.right = null;
return _obj;
}
//初始化二叉樹
if (typeof tree === 'number') {
this.insert(tree);
} else if (Array.isArray(tree)) {
this.bulkInsert(tree)
} else {
console.error('請輸入Number類型或者Array類型的參數')
}
}
insert(key) {
//添加一個新子樹
let newNode = this.Node(key);
let _insertNode = (node, newNode) => {
//判斷新二叉樹的值和原有節點的值
if (newNode.key < node.key) {
if (node.left === null) {
//判斷左節點是否爲空
node.left = newNode;
} else {
_insertNode(node.left, newNode)
}
} else {
if (node.right === null) {
//判斷右節點是否爲空
node.right = newNode;
} else {
_insertNode(node.right, newNode)
}
}
}
if (this.root === null) {
//若是沒有根節點,那麼把傳入的值當根節點
this.root = newNode;
} else {
//若是有根節點,那麼把傳入的值插到二叉樹上
_insertNode(this.root, newNode);
}
}
bulkInsert (nodes) {
nodes.forEach(key => {
//遍歷數組,插入子樹
this.insert(key);
})
}
showTree () {
//返回二叉樹對象
return this.root;
}
}
let nodes = [8,3,6,4,9,11,2,5,7];
let binaryTree = new BinaryTree(nodes);
let tree = binaryTree.showTree();複製代碼
class BinaryTree {
......//生成樹的代碼
inOrderTraverse (fn) {
//中序遍歷,傳入一個回調函數
let inOrderTraverseNode = (node, callback) => {
if (node !== null) {
inOrderTraverseNode(node.left, callback);
callback(node.key);
inOrderTraverseNode(node.right, callback);
}
}
inOrderTraverseNode(this.root, fn)
}
preOrderTraverse (fn) {
//先序遍歷,傳入一個回調函數
let preOrderTraverseNode = (node, callback) => {
if (node !== null) {
callback(node.key);
preOrderTraverseNode(node.left, callback);
preOrderTraverseNode(node.right, callback);
}
}
preOrderTraverseNode(this.root, fn)
}
postOrderTraverse (fn) {
//先序遍歷,傳入一個回調函數
let postOrderTraverseNode = (node, callback) => {
if (node !== null) {
postOrderTraverseNode(node.left, callback);
postOrderTraverseNode(node.right, callback);
callback(node.key);
}
}
postOrderTraverseNode(this.root, fn)
}
}
let nodes = [8,3,6,4,9,11,2,5,7];
let binaryTree = new BinaryTree(nodes);
let arr1 = [],
arr2 = [],
arr3 = [];
binaryTree.inOrderTraverse(key => {
arr1.push(key);//中序遍歷[2, 3, 4, 5, 6, 7, 8, 9, 11]
})
binaryTree.preOrderTraverse(key => {
arr2.push(key);//先序遍歷[8, 3, 2, 6, 4, 5, 7, 9, 11]
})
binaryTree.postOrderTraverse(key => {
arr3.push(key);//後序遍歷[2, 5, 4, 7, 6, 3, 11, 9, 8]
})複製代碼
class BinaryTree {
......//生成樹的代碼與三種遍歷代碼
min() {
let node = this.root;
if (node) {
//循環遍歷左子樹
while (node && node.left !== null) {
node = node.left;
}
return node.key;
}
}
max() {
let node = this.root;
if (node) {
//循環遍歷右子樹
while (node && node.right !== null) {
node = node.right;
}
return node.key;
}
}
}
let nodes = [8,3,6,4,9,11,2,5,7];
let binaryTree = new BinaryTree(nodes);
let min = binaryTree.min();//2
let max = binaryTree.max();//11複製代碼
class BinaryTree {
......//生成樹的代碼與三種遍歷代碼
search(key) {
let searchNode = (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)
}
}
let nodes = [8,3,6,4,9,11,2,5,7];
let binaryTree = new BinaryTree(nodes);
let inTree1 = binaryTree.showTree(2);//true
let inTree2 = binaryTree.showTree(1);//false複製代碼
class BinaryTree {
......//生成樹的代碼與三種遍歷代碼
remove(key) {
let findMinNode = (node, key) => {
//查找最小子節點
let node = node || this.root;
if (node) {
while (node && node.left !== null) {
node = node.left;
}
return node;
}
return null;
}
let removeNode = (node, key) => {
if (node === null) {
//若是爲null,返回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) {
//若是該節點沒有左右子樹,直接使其爲null
node = null;
return node;
}
if (node.left === null) {
//若是該節點只有右子樹,則將該節點指向它的右子樹
node = node.right;
return node;
} else if (node.right === null) {
//若是該節點只有左子樹,則將該節點指向它的左子樹
node = node.left;
return node;
}
if (node.left !== null && node.right !== null) {
//若是該節點有左右子樹,則把找到它的右子樹的最小子節點,並使該節點的值等於它的右子樹的最小子節點的值,而後刪除它的右子樹的最小子節點
let aux = findMinNode(node.right);
node.key = aux;
node.right = removeNode(node.right, aux.key);
return node;
}
}
}
this.root = removeNode(this.root, key)
}
}
let nodes = [8,3,6,4,9,11,2,5,7];
let binaryTree = new BinaryTree(nodes);複製代碼
class BinaryTree {
constructor(tree = []) {
this.root = null;//樹根
this.Node = key => {
//生成一個新的子樹
let _obj = Object.create(null, {});
_obj.key = key;
_obj.left = null;
_obj.right = null;
return _obj;
}
//初始化二叉樹
if (typeof tree === 'number') {
this.insert(tree);
} else if (Array.isArray(tree)) {
this.bulkInsert(tree)
} else {
console.error('請輸入Number類型或者Array類型的參數')
}
}
insert(key) {
//添加一個新子樹
let newNode = this.Node(key);
let _insertNode = (node, newNode) => {
//判斷新二叉樹的值和原有節點的值
if (newNode.key < node.key) {
if (node.left === null) {
//判斷左節點是否爲空
node.left = newNode;
} else {
_insertNode(node.left, newNode)
}
} else {
if (node.right === null) {
//判斷右節點是否爲空
node.right = newNode;
} else {
_insertNode(node.right, newNode)
}
}
}
if (this.root === null) {
//若是沒有根節點,那麼把傳入的值當根節點
this.root = newNode;
} else {
//若是有根節點,那麼把傳入的值插到二叉樹上
_insertNode(this.root, newNode);
}
}
bulkInsert (nodes) {
nodes.forEach(key => {
//遍歷數組,插入子樹
this.insert(key);
})
}
showTree () {
//返回二叉樹對象
return this.root;
}
inOrderTraverse (fn) {
let inOrderTraverseNode = (node, callback) => {
if (node !== null) {
inOrderTraverseNode(node.left, callback);
callback(node.key);
inOrderTraverseNode(node.right, callback);
}
}
inOrderTraverseNode(this.root, fn)
}
preOrderTraverse (fn) {
let preOrderTraverseNode = (node, callback) => {
if (node !== null) {
callback(node.key);
preOrderTraverseNode(node.left, callback);
preOrderTraverseNode(node.right, callback);
}
}
preOrderTraverseNode(this.root, fn)
}
postOrderTraverse (fn) {
let postOrderTraverseNode = (node, callback) => {
if (node !== null) {
postOrderTraverseNode(node.left, callback);
postOrderTraverseNode(node.right, callback);
callback(node.key);
}
}
postOrderTraverseNode(this.root, fn)
}
min() {
let node = this.root;
if (node) {
while (node && node.left !== null) {
node = node.left;
}
return node.key;
}
}
max() {
let node = this.root;
if (node) {
while (node && node.right !== null) {
node = node.right;
}
return node.key;
}
}
search(key) {
let searchNode = (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)
}
remove(key) {
let findMinNode = (node, key) => {
let node = node || this.root;
if (node) {
while (node && node.left !== null) {
node = node.left;
}
return node;
}
return null;
}
let 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;
}
if (node.left !== null && node.right !== null) {
let aux = findMinNode(node.right);
node.key = aux;
node.right = removeNode(node.right, aux.key);
return node;
}
}
}
this.root = removeNode(this.root, key)
}
}
let nodes = [8,3,6,4,9,11,2,5,7];
let binaryTree = new BinaryTree(nodes);複製代碼