javascript实现二叉树
二叉树是神马我就不多说了。
直接上方法
首先,创建二叉树的节点
二叉树包含 自身数据(data),左节点(left),右节点(right),显示自己的数据(show)
function Node(data, left, right) { this.data = data; this.left = left; this.right = right; this.show = show; }
最简单的,显示方法
function show() { return this.data; }
接下来声明二叉树的构造函数
我们默认根节点为null,初始化他们的方法
function BST() { this.root = null; this.insert = insert; // 插入操作 this.inOrder = inOrder; // 中序遍历 this.getMin = getMin; // 找出最小值 this.getMax = getMax; // 找出最大值 this.find = find; // 找出指定数据 }
插入节点的操作
// 插入节点 function insert(data) { var n = new Node(data, null, null);//声明一个新的节点 if (this.root == null) { // 如果节点为根null,声明的节点即为跟节点 this.root = n; } else { // 如果不是的话,从根节点开始找可以插入的位置 var current = this.root; //声明当前遍历节点,初始为根节点 var parent; // 当前节点的父节点 while (true) { // 循环遍历 parent = current; // 存储当前节点,后边当前节点会指向其子节点 if (data < current.data) { // 如果插入的数据小于当前节点的数据 current = current.left; // 当前节点变为其左节点 if (current == null) { // 如果当前节点为null 则把插入到当前节点 parent.left = n; break; } } else {// 如果大于的话插入右节点 current = current.right; if (current == null) { parent.right = n; break; } } } } }
中序遍历实现:
// 中序遍历--采用递归实现 function inOrder(node) { if (!(node == null)) { // 判断当前节点是否为null inOrder(node.left); //递归调用,传入当前节点的左节点 console.log(node.show() + " "); // 打印当前节点 inOrder(node.right); // 递归调用,当前节点的右节点 } }
先序遍历和后序遍历
注意:三个遍历方式的区别在于打印当前接待您的位置,和递归函数的调用位置。
// 先序遍历 function preOrder(node) { if (!(node == null)) { console.log(node.show()); preOrder(node.left); preOrder(node.right); } } // 后序遍历 function postOrder(node) { if (!(node == null)) { postOrder(node.left); postOrder(node.right); console.log(node.show()); } }
查找最大最小值的实现,道理相同
// 查找最小值 function getMin() { // 由于二叉树是根据大小插入的(大于父节点的在右边,小于父节点的在左边) // 所以最小值一定在左节点的尽头,反之最大值在右节点的尽头 var current = this.root;// 将当前节点指向根节点 while (!(current.left == null)) { // 判断当前节点的左节点是否为null current = current.left; // 向下找 } return current.data; // 返回最左节点 } // 查找最大值 function getMax() { var current = this.root; while (!(current.right == null)) { current = current.right; } return current.data; }
查找特定节点:
// 查找特定值 function find(data) { var current = this.root; while (current != null) { // 根据数据大小一层一层向下遍历寻找 if (current.data == data) { return current; } else if (data < current.data) { current = current.left; } else { current = current.right; } } return null; }
汇总:
// 创建单个节点 function Node(data, left, right) { this.data = data; this.left = left; this.right = right; this.show = show; } function show() { return this.data; } function BST() { this.root = null; this.insert = insert; this.inOrder = inOrder; this.getMin = getMin; this.getMax = getMax; this.find = find; this.remove = remove; } // 插入节点 function insert(data) { var n = new Node(data, null, null);//声明一个新的节点 if (this.root == null) { // 如果节点为根null,声明的节点即为跟节点 this.root = n; } else { // 如果不是的话,从根节点开始找可以插入的位置 var current = this.root; //声明当前遍历节点,初始为根节点 var parent; // 当前节点的父节点 while (true) { // 循环遍历 parent = current; // 存储当前节点,后边当前节点会指向其子节点 if (data < current.data) { // 如果插入的数据小于当前节点的数据 current = current.left; // 当前节点变为其左节点 if (current == null) { // 如果当前节点为null 则把插入到当前节点 parent.left = n; break; } } else {// 如果大于的话插入右节点 current = current.right; if (current == null) { parent.right = n; break; } } } } } // 中序遍历--采用递归实现 function inOrder(node) { if (!(node == null)) { // 判断当前节点是否为null inOrder(node.left); //递归调用,传入当前节点的左节点 console.log(node.show() + " "); // 打印当前节点 inOrder(node.right); // 递归调用,当前节点的右节点 } } // 先序遍历 function preOrder(node) { if (!(node == null)) { console.log(node.show()); preOrder(node.left); preOrder(node.right); } } // 后序遍历 function postOrder(node) { if (!(node == null)) { postOrder(node.left); postOrder(node.right); console.log(node.show()); } } // 查找最小值 function getMin() { // 由于二叉树是根据大小插入的(大于父节点的在右边,小于父节点的在左边) // 所以最小值一定在左节点的尽头,反之最大值在右节点的尽头 var current = this.root;// 将当前节点指向根节点 while (!(current.left == null)) { // 判断当前节点的左节点是否为null current = current.left; // 向下找 } return current.data; // 返回最左节点 } // 查找最大值 function getMax() { var current = this.root; while (!(current.right == null)) { current = current.right; } return current.data; } // 查找特定值 function find(data) { var current = this.root; while (current != null) { // 根据数据大小一层一层向下遍历寻找 if (current.data == data) { return current; } else if (data < current.data) { current = current.left; } else { current = current.right; } } return null; } // 删除节点 function remove(data) { root = removeNode(this.root, data); console.log(root) } function removeNode(node, data) { if (node == null) { return null; } if (data == node.data) { // 没有子节点的节点 if (node.left == null && node.right == null) { return null; } // 没有左节点的节点 if (node.left == null) { return node.right; } // 没有右节点的节点 if (node.right == null) { return node.left; } // 有两个子节点的节点 var tempNode = getSmallest(node.right); node.data = tempNode.data; node.right = removeNode(node.right, tempNode.data); return node; } else if (data < node.data) { node.left = removeNode(node.left, data); return node; } else { node.right = removeNode(node.right, data); return node; } } // 测试 var nums = new BST(); nums.insert(23); nums.insert(45); nums.insert(16); nums.insert(37); nums.insert(3); nums.insert(99); nums.insert(22); console.log("最小值:" + nums.getMin()); console.log("最大值:" + nums.getMax());
尴尬的是,remove方法没有实现,欢迎留言告知。
如有不足,请多指教。