问:
- 莫里斯遍历
- 莫里斯遍历改先中后序遍历
解:
- 流程:①判断当前是否有左节点,没有则当前节点指向右节点;②找到左树的最右节点,若最右节点的右节点为null,将其指向当前节点,当前节点指向左节点;若最右节点的右节点为当前节点,将其重新指向null,当前节点指向右节点
function Morris(root) {
let curNode = root
while (curNode) {
if (curNode.left) {
let mostRight = curNode.left
while (mostRight.right && mostRight.right !== curNode) {
mostRight = mostRight.right
}
if (mostRight.right === null) {
mostRight.right = curNode
curNode = curNode.left
continue
}
if (mostRight.right === curNode) {
mostRight.right = null
}
}
curNode = curNode.right
}
}
- 先序:只到达一次的节点直接打印;到达两次的节点,第一次到达时打印
function Morris(root) {
let curNode = root
while (curNode) {
if (curNode.left) {
let mostRight = curNode.left
while (mostRight.right && mostRight.right !== curNode) {
mostRight = mostRight.right
}
if (mostRight.right === null) {
console.log(curNode)
mostRight.right = curNode
curNode = curNode.left
continue
}
if (mostRight.right === curNode) {
mostRight.right = null
}
}
console.log(curNode)
curNode = curNode.right
}
}
中序:只到达一次的节点直接打印;到达两次的节点,第二次到达时打印
function Morris(root) {
let curNode = root
while (curNode) {
if (curNode.left) {
let mostRight = curNode.left
while (mostRight.right && mostRight.right !== curNode) {
mostRight = mostRight.right
}
if (mostRight.right === null) {
mostRight.right = curNode
curNode = curNode.left
continue
}
if (mostRight.right === curNode) {
mostRight.right = null
}
}
console.log(curNode)
curNode = curNode.right
}
}
后序:到达两次的节点,第二次到达时,逆序打印左树的右边界
function Morris(root) {
let curNode = root
while (curNode) {
if (curNode.left) {
let pre = null
let mostRight = curNode.left
while (mostRight.right && mostRight.right !== curNode) {
mostRight = mostRight.right
}
if (mostRight.right === null) {
mostRight.right = curNode
curNode = curNode.left
continue
}
if (mostRight.right === curNode) {
mostRight.right = null
printNode(curNode.left)
}
}
console.log(curNode)
curNode = curNode.right
}
}
// 处理完再反转回去
function printNode(node) {
const reverseNode = reverseTree(node)
let curNode = reverseNode
while (curNode) {
console.log(curNode)
curNode = curNode.right
}
reverseTree (reverseNode)
}
// 类似反转链表
function reverseTree(node) {
let pre = null
let temp = null
while(node){
temp = node.right
node.right = pre
pre = node
node = temp
}
return pre
}