二叉樹
- 二叉樹排序是一種數據結構、根據左孩子小於根節點、右孩子大於根節點的順序進行構造
- 任意給一個數組,對其進行二叉樹排序。
function BinaryTree() {
// 二叉樹的節點
let Node = function (key) {
this.key = key; //當前節點的值
this.left = null; // 左孩子
this.right = null; // 右孩子
}
// 插入子節點
let insertNode = function (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);
}
}
}
// 初始化根節點、就是一個數組的第一個元素當作二叉樹的根節點
let root = null;
this.insert = function (key) {
let newNode = new Node(key);
if(root === null){
root = newNode;
}else{
insertNode(root,newNode)
}
};
// 查看二叉樹結構
this.show = function () {
console.log(root);
}
// 中序遍歷
let inOrderTraverseNode = function (node,callback) {
if(node !== null){
inOrderTraverseNode(node.left,callback);
callback(node.key);
inOrderTraverseNode(node.right,callback)
}
}
this.inOrderTraverse = function (callback) {
inOrderTraverseNode(root,callback)
}
// 前序遍歷
let preOrderTraverseNode = function (node,callback) {
if(node !== null){
callback(node.key);
preOrderTraverseNode(node.left,callback);
preOrderTraverseNode(node.right,callback);
}
}
this.preOrderTraverse = function (callback) {
preOrderTraverseNode(root,callback)
}
// 後序遍歷
let nextOrderTraverseNode = function (node,callback) {
if(node !== null){
nextOrderTraverseNode(node.left,callback);
nextOrderTraverseNode(node.right,callback);
callback(node.key);
}
}
this.nextOrderTraverse = function (callback) {
nextOrderTraverseNode(root,callback);
}
}
let nodes = [18,13,102,11,6,14,4,7,131];
const bt = new BinaryTree();
nodes.forEach( key => {
bt.insert(key)
})
bt.show()
// 中序遍歷
// bt.inOrderTraverse((key) => {
// console.log(key);
// })
// 前序遍歷
// bt.preOrderTraverse((key) => {
// console.log(key);
// })
// 後序遍歷
bt.nextOrderTraverse((key) => {
console.log(key);
})
- 中序遍歷
- 首先遍歷左子樹、而後遍歷根節點、最後遍歷右子樹 -- 左-根-右
- 做用: 將一個二叉樹進行升序排序輸出
- 前序遍歷
- 首先遍歷根節點、而後遍歷左子樹、最後遍歷右子樹 -- 根-左-右
- 做用: 複製一個二叉樹、複製一個二叉樹比從新生成一個二叉樹的效率高10倍左右
- 後序遍歷
- 首先遍歷左子樹、而後遍歷右子樹、最後遍歷根節點 -- 左-右-根
- 適用於操做系統的文件遍歷
- 查找最小值
- 查找最大值
- 查找某一個值
// 查找最小值
let minNode = function (node) {
if(node){
while(node && node.left !== null){
node = node.left;
}
return node.key;
}
return null;
}
this.min = function () {
return minNode(root);
}
// 查找最大值
let maxNode = function (node) {
if(node){
while(node && node.right !== null){
node = node.right;
}
return node.key;
}
return null;
}
this.max = function () {
return maxNode(root);
}
// 查找某個具體的值
let findNode = function (node,key) {
if(node === null){
return false;
}
// 如果查找的值小於當前節點的值,那麼就去其左子樹進行查找
// 如果大於,就去右子樹進行查找
// 如果相等 則返回true 表明存在
if(key < node.key){
return findNode(node.left,key)
}else if(key > node.key){
return findNode(node.right, key)
}else{
return true;
}
}
this.find = function (key) {
return findNode(root,key);
}
// 最小值
// console.log(bt.min());
// 最大值
// console.log(bt.max());
// 查找某一個值是否存在二叉樹中
console.log(bt.find(12)); // false
console.log(bt.find(14)); // true
// 刪除子節點
let removeNode = function (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;
}
// 含有左右子節點
let aux = findMinNode(node.right);
node.key = aux.key;
node.right = removeNode(node.right,aux.key);
return node;
}
}
this.remove = function (key) {
root = removeNode(root,key);
}
// 刪除葉子節點
bt.inOrderTraverse((key) => {
console.log(key);
})
console.log('-----');
bt.remove(4)
bt.inOrderTraverse((key) => {
console.log(key);
})
function BinaryTree() {
// 二叉樹的節點
let Node = function (key) {
this.key = key; //當前節點的值
this.left = null; // 左孩子
this.right = null; // 右孩子
}
// 插入子節點
let insertNode = function (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);
}
}
}
// 初始化根節點、就是一個數組的第一個元素當作二叉樹的根節點
let root = null;
this.insert = function (key) {
let newNode = new Node(key);
if(root === null){
root = newNode;
}else{
insertNode(root,newNode)
}
};
// 查看二叉樹結構
this.show = function () {
console.log(root);
}
// 中序遍歷
let inOrderTraverseNode = function (node,callback) {
if(node !== null){
inOrderTraverseNode(node.left,callback);
callback(node.key);
inOrderTraverseNode(node.right,callback)
}
}
this.inOrderTraverse = function (callback) {
inOrderTraverseNode(root,callback)
}
// 前序遍歷
let preOrderTraverseNode = function (node,callback) {
if(node !== null){
callback(node.key);
preOrderTraverseNode(node.left,callback);
preOrderTraverseNode(node.right,callback);
}
}
this.preOrderTraverse = function (callback) {
preOrderTraverseNode(root,callback)
}
// 後序遍歷
let nextOrderTraverseNode = function (node,callback) {
if(node !== null){
nextOrderTraverseNode(node.left,callback);
nextOrderTraverseNode(node.right,callback);
callback(node.key);
}
}
this.nextOrderTraverse = function (callback) {
nextOrderTraverseNode(root,callback);
}
// 查找最小值
let minNode = function (node) {
if(node){
while(node && node.left !== null){
node = node.left;
}
return node.key;
}
return null;
}
this.min = function () {
return minNode(root);
}
// 查找最大值
let maxNode = function (node) {
if(node){
while(node && node.right !== null){
node = node.right;
}
return node.key;
}
return null;
}
this.max = function () {
return maxNode(root);
}
// 查找某個具體的值
let findNode = function (node,key) {
if(node === null){
return false;
}
// 如果查找的值小於當前節點的值,那麼就去其左子樹進行查找
// 如果大於,就去右子樹進行查找
// 如果相等 則返回true 表明存在
if(key < node.key){
return findNode(node.left,key)
}else if(key > node.key){
return findNode(node.right, key)
}else{
return true;
}
}
this.find = function (key) {
return findNode(root,key);
}
// 查找最小子節點
let findMinNode = function (node) {
if(node){
while(node && node.left !== null){
return node
}
}
return null;
}
// 刪除葉子節點
let removeNode = function (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;
}
// 含有左右子節點
let aux = findMinNode(node.right);
node.key = aux.key;
node.right = removeNode(node.right,aux.key);
return node;
}
}
this.remove = function (key) {
root = removeNode(root,key);
}
}
let nodes = [18,13,102,11,6,14,4,7,131];
const bt = new BinaryTree();
nodes.forEach( key => {
bt.insert(key)
})
// bt.show()
// 中序遍歷
// bt.inOrderTraverse((key) => {
// console.log(key);
// })
// 前序遍歷
// bt.preOrderTraverse((key) => {
// console.log(key);
// })
// 後序遍歷
// bt.nextOrderTraverse((key) => {
// console.log(key);
// })
// 最小值
// console.log(bt.min());
// 最大值
// console.log(bt.max());
// 查找某一個值是否存在二叉樹中
// console.log(bt.find(12)); // false
// console.log(bt.find(14)); // true
// 刪除葉子節點
bt.inOrderTraverse((key) => {
console.log(key);
})
console.log('-----');
bt.remove(4)
bt.inOrderTraverse((key) => {
console.log(key);
})