This commit is contained in:
linghuam 2019-05-20 20:38:58 +08:00
parent f2bde64b89
commit 1743cd0f8c
2 changed files with 87 additions and 28 deletions

View File

@ -1,32 +1,42 @@
function traveseTree(root, callback) { function removeNode(node, value) {
var pCur = root, pLast = null, stack = []; if (node == null) return null;
if (root == null) return; if (value < node.value) {
// 先把pCur移到左子树最下边 node.left = removeNode(node.left, value);
while(pCur) { return node;
stack.push(pCur); } else if (value > node.value) {
pCur = pCur.left; node.right = removeNode(node.right, value);
} return node;
while(stack.length) { } else {
pCur = stack.pop(); //情况1节点为叶节点有零个子节点的节点
//一个根节点被访问的前提是:无右子树或右子树已被访问过 if(node.left == null && node.right == null) {
if (pCur.right == null || pCur.right == pLast) { node = null;
callback(pCur); return node;
pLast = pCur;
} }
/*elseelse if: //情况2只有一个子节点的节点
else if (pCur->lchild == pLastVisit)//若左子树刚被访问过,则需先进入右子树(根节点需再次入栈) if (node.left == null) {
因为上面的条件没通过就一定是下面的条件满足仔细想想 node = node.right;
*/ return node;
else { } else if(node.right == null) {
// 根节点再次入栈 node = node.left;
stack.push(pCur); return node;
// 进入右子树,且可肯定右子树一定不为空 }
pCur = pCur.right; //情况3有两个子节点的节点
while(pCur) { // 先找到右边子树节点的最小值节点
stack.push(pCur); // 再用最小值节点的值更新当前节点的值
pCur = pCur.left; // 最后删除右边子树最小值节点
var findMinNode = function(node) {
if (node) {
while(node && node.left !== null) {
node = node.left;
}
return node;
} }
return null;
} }
var aux = findMinNode(node.right);
node.value = aux.value;
node.right = removeNode(node.right, aux.value);
return node;
} }
} }
var root = { var root = {
@ -90,4 +100,4 @@ var root = {
} }
} }
}; };
traveseTree(root, e => {e && e.value && console.log(e.value);}); removeNode(root, 15);

View File

@ -297,4 +297,53 @@ function traveseTree(root, callback) {
### 树的查找 ### 树的查找
* 最小值:左子树最下边
* 最大值:右子树最下边
* 特定值:先序遍历
### 树的删除 ### 树的删除
```js
// 删除值为value的节点
function removeNode(node, value) {
if (node == null) return null;
if (value < node.value) {
node.left = removeNode(node.left, value);
return node;
} else if (value > node.value) {
node.right = removeNode(node.right, value);
return node;
} else {
//情况1节点为叶节点有零个子节点的节点
if(node.left == null && node.right == null) {
node = null;
return node;
}
//情况2只有一个子节点的节点
if (node.left == null) {
node = node.right;
return node;
} else if(node.right == null) {
node = node.left;
return node;
}
//情况3有两个子节点的节点
// 先找到右边子树节点的最小值节点
// 再用最小值节点的值更新当前节点的值
// 最后删除右边子树最小值节点
var findMinNode = function(node) {
if (node) {
while(node && node.left !== null) {
node = node.left;
}
return node;
}
return null;
}
var aux = findMinNode(node.right);
node.value = aux.value;
node.right = removeNode(node.right, aux.value);
return node;
}
}
```