函数运行时,会产生一个栈用来存放数据,当遍历到目的节点时,操作结束以后,就会自动执行出栈操作,所以每次执行完毕指针都会自动跳回根节点。可以在开发者模式里打断点看到全过程。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>二叉树排序</title>
</head>
<body>
</body>
<script type="text/javascript">
function binaryTree() {
function node(value) { //封装节点数据结构
this.value = value;
this.left = null;
this.right = null;
}
var rootNode = null;
function insertNode (oldnode, newnode) { //开始排序,小在左,大在右
if (oldnode.value > newnode.value) {
if (oldnode.left === null) {
oldnode.left = newnode;
} else {
insertNode(oldnode.left, newnode);
}
} else {
if (oldnode.right === null) {
oldnode.right = newnode;
} else {
insertNode(oldnode.right, newnode);
}
}
}
this.insert = function (value) {
var newNode = new node(value);
if (rootNode === null) { //创建根节点
rootNode = newNode;
} else {
insertNode(rootNode,newNode);
}
}
function Dlrmidmethod (node, midcallback) { //中序遍历
if (node !== null) {
Dlrmidmethod(node.left, midcallback);
midcallback(node.value);
Dlrmidmethod(node.right, midcallback);
}
}
this.Dlrmid = function (midcallback) { //中序遍历
Dlrmidmethod(rootNode, midcallback);
}
function Dlrpremethod (node, precallback) { //前序遍历
if (node !== null) {
precallback(node.value);
Dlrpremethod(node.left, precallback);
Dlrpremethod(node.right, precallback);
}
}
this.Dlrpre = function (precallback) { //前序遍历
Dlrpremethod(rootNode, precallback)
}
function Dlrlastmethod (node, lastcallback) { //后序遍历
if (node !== null) {
Dlrlastmethod(node.left, lastcallback);
Dlrlastmethod(node.right, lastcallback);
lastcallback(node.value);
}
}
this.Dlrlast = function (lastcallback) { //后序遍历
Dlrlastmethod(rootNode, lastcallback)
}
function minnodeMethod (node) { //求最小值,最大值找右节点
if (node) {
while(node && node.left !== null) {
node = node.left;
}
console.log('最小值' + node.value);
return node;
}
return null;
}
this.minnode = function () {
var rootNode = rootNode;
return minnodeMethod(rootNode);
}
var searchNode = function (node, value) { //查找
if (node === null) {
console.log('查找失败');
} else {
if (value > node.value) {
searchNode(node.right, value);
} else if (value < node.value) {
searchNode(node.left, value);
} else {
console.log(node);
console.log('查找成功');
}
}
}
this.search = function (value) {
var rootNode = rootNode;
return searchNode(rootNode, value);
}
var thisMin = function (node) {
while(node.left!=null){
node=node.left;
}
return node;
}
var deleteNode = function (node, value) {
if (node === null) {
console.log('查找失败');
return null;
}
if (value > node.value) {
node.right = deleteNode(node.right, value);
return node;
} else if (value < node.value) {
node.left = deleteNode(node.left, value);
return node;
} else {
if (node.left === null && node.right === null) { //删除没有孩子节点的节点
node = null;
console.log('删除成功');
console.log(node);
return null;
}
if(node.left === null) { //删除有一个孩子节点的节点
node = node.right;
console.log('删除成功1');
return node;
} else if(node.right === null) {
console.log(node);
node = node.left;
console.log('删除成功2');
return node;
} else if (node.left !== null && node.right !== null) { //删除有两个孩子节点的节点
var m = thisMin(node.right);
node.value = m.value;
node.right = deleteNode(node.right, m.value);
console.log('删除成功3');
return node;
}
}
return node;
}
this.deleteit = function (value) {
rootNode = deleteNode(rootNode, value);
}
}
var tree = [4, 2, 1, 3, 8, 6, 11, 5, 7, 9, 12];
var bt = new binaryTree(); //实例化
tree.forEach(function sort(value) { //开始排序
bt.insert(value) //调用对象的方法
});
function midcallback(node) {
console.log('中序遍历' + node);
}
bt.Dlrmid(midcallback);
function precallback(node) {
console.log('前序遍历' + node);
}
bt.Dlrpre(precallback);
function lastcallback(node) {
console.log('后序遍历' + node);
}
bt.Dlrlast(lastcallback);
bt.minnode();
bt.deleteit(8);
</script>
</html>