js二叉树

class Node {
	constructor(key) {
		this.key = key;// 节点值
		this.left = null;// 左指针
		this.right = null;// 右指针
	}
}
// 二叉树
export default class BinaryTree {
	constructor() {
		this.root = null;// 根节点
	}
	insert(key) {// api--插入
		const newNode = new Node(key);
		if (this.root === null) {// 设置根节点
			this.root = newNode;
		}
		method.insertNode(this.root, newNode);
	}
	// callback为访问节点时执行的操作 中序排序
	inorderTraversal(callback) {// api--中序遍历
		method.inorderTraversalNode(this.root, callback);
	}
	preOrderTraversal(callback) {// api--前序遍历
		method.preOrderTraversalNode(this.root, callback);
	}
	postOrderTraversal(callback) {// api--后序遍历
		method.postOrderTraversalNode(this.root, callback);
	}
	max() { // 查找最大
		return method.maxNode(this.root);
	}
	min() {
		return method.minNode(this.root);
	}
	search(key) {
		return method.searchNode(this.root, key);
	}
	remove(key) {
		this.root = method.removeNode(this.root, key);
	}
}
// method
const method = {
	insertNode(root, newNode) {
		if (newNode.key < root.key) {// 进入左子树
			if (root.left === null) {// 左子树为空
				root.left = newNode;
			} else {// 左子树已存在
				method.insertNode(root.left, newNode);
			}
		} else if (newNode.key > root.key) {// 进入右子树
			if (root.right === null) {// 右子树为空
				root.right = newNode;
			} else {// 右子树已存在
				method.insertNode(root.right, newNode);
			}
		}
	},
	inorderTraversalNode(node, callback) {
		if (node) {// 当前节点
			method.inorderTraversalNode(node.left, callback);// 遍历左子树
			callback(node);// 访问节点
			method.inorderTraversalNode(node.right, callback);// 遍历右子树
		}
	},
	preOrderTraversalNode(node, callback) {
		if (node) {// 当前节点
			callback(node);// 访问节点
			method.preOrderTraversalNode(node.left, callback);// 遍历左子树
			method.preOrderTraversalNode(node.right, callback);// 遍历右子树
		}
	},
	postOrderTraversalNode(node, callback) {
		if (node) {// 当前节点
			method.postOrderTraversalNode(node.left, callback);// 遍历左子树
			method.postOrderTraversalNode(node.right, callback);// 遍历右子树
			callback(node);// 访问节点
		}
	},
	// 根据排序二叉树的特点,右子树的值都大于父节点的值。只需要进入节点的右子树查找,当某个节点的右子树为空时,该节点就是最大值节点。
	maxNode(node) {
		if (node) {
			while (node.right !== null) {// 右子树不为空时
				node = node.right;
			}
			return node.key;
		}
		return null;
	},
	// 查找最小值。根据排序二叉树的特点,左子树的值都小于父节点的值。只需要进入节点的左子树查找,当某个节点的左子树为空时,该节点就是最小值节点。
	minNode(node) {
		if (node) {
			while (node.left !== null) {// 左子树不为空时
				node = node.left;
			}
			return node.key;
		}
		return null;
	},
	// 根据排序二叉树的特点,比较给定值与节点值,小于时进入节点左子树。大于时进入节点右子树。等于时返回真。层层对比,最后如果子树为空,则表示没有找到。
	searchNode(node, key) {
		if (node === null) {// 没有找到
			return false;
		}
		if (key < node.key) {// 进入左子树
			return method.searchNode(node.left, key);
		} else if (key > node.key) {// 进入右子树
			return method.searchNode(node.right, key);
		} else {// 找到了
			return true;
		}
	},
	removeNode(node, key) {
		if (node === null) {// 没有找到值对应的节点
			return null;
		}
		if (key < node.key) {// 给定值小于当前节点值
			node.left = method.removeNode(node.left, key);
			return node;
		} else if (key > node.key) {// 给定值大于当前节点值
			node.right = method.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;
			}

			// 节点存在左右子树时,先去右子树里找到最小值,然后用最小值替换节点值,最后进入右子树删除最小值对应的节点。
			const minKey = method.minNode(node.right);
			node.key = minKey;
			method.removeNode(node.right, minKey);
			return node;
		}
	}
};

		// /// 使用
		// // // 实例化二叉树
		// const binaryTree = new BinaryTree();
		// // // key值
		// const keys = [1,19, 8, 15, 24, 45, 12, 5];
		// // // 生成排序二叉树
		// keys.forEach(key => binaryTree.insert(key));
		// // console.log(binaryTree)
		// // 中序遍历
		// binaryTree.inorderTraversal(node => console.log(node.key));
		// // 前序遍历
		// // binaryTree.preOrderTraversal(node => console.log(node.key));
		// // 后序遍历
		// // binaryTree.postOrderTraversal(node => console.log(node.key));
		// // binaryTree.remove(8);
		// console.log(binaryTree)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值