Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Morris遍历树 #35

Open
YBFACC opened this issue Jul 29, 2020 · 0 comments
Open

Morris遍历树 #35

YBFACC opened this issue Jul 29, 2020 · 0 comments

Comments

@YBFACC
Copy link
Owner

YBFACC commented Jul 29, 2020

Morris遍历

可以只使用O(1)空间完成树的遍历

核心就是子树的最右侧的节点的右指针指向父节点。

前序

var Morris_pre = function (root) {
  if (!root) return
  let curr = root
  while (curr) {
    if (curr.left) {
      let proNode = curr.left
      while (proNode.right && proNode.right !== curr) {
        proNode = proNode.right
      }
      if (!proNode.right) {
        console.log(curr.val)
        proNode.right = curr
        curr = curr.left
      } else {
        curr = curr.right
        proNode.right = null
      }
    } else {
      console.log(curr.val)
      curr = curr.right
    }
  }
}

中序

var Morris_mid = function (root) {
  if (!root) return
  let curr = root
  while (curr) {
    if (curr.left) {
      let proNode = curr.left
      while (proNode.right && proNode.right !== curr) {
        proNode = proNode.right
      }
      if (!proNode.right) {
        proNode.right = curr
        curr = curr.left
      } else {
        console.log(curr.val)
        curr = curr.right
        proNode.right = null
      }
    } else {
      console.log(curr.val)
      curr = curr.right
    }
  }
}

后序

有一个反转输出的过程

var Morris_post = function (root) {
  if (!root) return
  let curr = root
  while (curr) {
    if (curr.left) {
      let proNode = curr.left
      while (proNode.right && proNode.right !== curr) {
        proNode = proNode.right
      }
      if (!proNode.right) {
        proNode.right = curr
        curr = curr.left
        continue
      } else {
        proNode.right = null
        print(curr.left)
      }
    }
    curr = curr.right
  }
  print(root)
}

function print(node) {
  const tail = reverse(node)
  let temp = tail
  while (temp) {
    console.log(temp.val)
    temp = temp.right
  }
  reverse(tail)
}

function reverse(node) {
  let pre, next
  while (node) {
    ;[next, node.right] = [node.right, pre]
    ;[pre, node] = [node, next]
  }
  return pre
}

参考

JS中的二叉树遍历

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant