morris前序

  1. //morris前序
  2. public void morrisPreOrder(Node head) {
  3. Node cur1 = head;
  4. Node cur2 = null;//左子节点
  5. while (cur1 != null) {
  6. cur2 = cur1.left;//当前节点的左子节点
  7. if (cur2 != null) {
  8. //循环遍历到左子节点的最右子节点
  9. while (cur2.right != null && cur2.right != cur1) {
  10. cur2 = cur2.right;
  11. }
  12. //如过最右节点未指向cur1,则使之指向cur1,并略过后续代码;
  13. if (cur2.right == null) {
  14. cur2.right = cur1;
  15. System.out.print(cur1.value + " ");//遇见父节点,先打印父节点
  16. cur1 = cur1.left;
  17. continue;
  18. } else {
  19. //如过最右节点已指向cur1,恢复,则使之指向null,
  20. cur2.right = null;
  21. }
  22. } else {
  23. //如果cur1.left 为null,说明没有左子节点,在切换到右子树之前先打印父节点
  24. System.out.print(cur1.value + " ");
  25. }
  26. cur1 = cur1.right;
  27. }
  28. System.out.println();
  29. }

morris中序

  1. //morris中序
  2. public void morrisInOrder(Node head) {
  3. Node cur1 = head;
  4. Node cur2 = null;//左子节点
  5. while (cur1 != null) {
  6. cur2 = cur1.left;//当前节点的左子节点
  7. if (cur2 != null) {
  8. //循环遍历到左子节点的最右子节点
  9. while (cur2.right != null && cur2.right != cur1) {
  10. cur2 = cur2.right;
  11. }
  12. //如过最右节点未指向cur1,则使之指向cur1,并略过后续代码;
  13. if (cur2.right == null) {
  14. cur2.right = cur1;
  15. cur1 = cur1.left;
  16. continue;
  17. } else {
  18. //如过最右节点已指向cur1,恢复,则使之指向null,
  19. cur2.right = null;
  20. }
  21. }
  22. //如果cur1.left 为null,则说明没有左子树,则开始打印父节点;
  23. System.out.print(cur1.value + " ");
  24. cur1 = cur1.right;
  25. }
  26. System.out.println();
  27. }

morris后序

  1. //morris后序
  2. public void morrisPostOrder(Node head) {
  3. Node cur1 = head;
  4. Node cur2 = null;//左子节点
  5. while (cur1 != null) {
  6. cur2 = cur1.left;//当前节点的左子节点
  7. if (cur2 != null) {
  8. //循环遍历到左子节点的最右子节点
  9. while (cur2.right != null && cur2.right != cur1) {
  10. cur2 = cur2.right;
  11. }
  12. //如过最右节点未指向cur1,则使之指向cur1,并略过后续代码;
  13. if (cur2.right == null) {
  14. cur2.right = cur1;
  15. cur1 = cur1.left;
  16. continue;
  17. } else {
  18. //如过最右节点已指向cur1,恢复,则使之指向null,
  19. cur2.right = null;
  20. printEdge(cur1.left);
  21. }
  22. }
  23. cur1 = cur1.right;
  24. }
  25. printEdge(head);
  26. System.out.println();
  27. }
  28. //打印节点
  29. public void printEdge(Node head) {
  30. Node tail = reverse(head);
  31. Node cur = tail;
  32. while (cur != null) {
  33. System.out.print(cur.value + " ");
  34. cur = cur.right;
  35. }
  36. //恢复链表
  37. reverse(tail);
  38. }
  39. //反转节点的右子节点链
  40. public Node reverse(Node head) {
  41. Node pre = null;
  42. Node next = null;
  43. while (head != null) {
  44. next = head.right;
  45. head.right = pre;
  46. pre = head;
  47. head = next;
  48. }
  49. return pre;
  50. }

测试

  1. /**
  2. * @Description:遍历二叉树的神级方法 morris
  3. * @Author: lizhouwei
  4. * @CreateDate: 2018/4/14 17:15
  5. */
  6. public class Chapter3_5 {
  7. //测试
  8. public static void main(String[] args) {
  9. Chapter3_5 chapter = new Chapter3_5();
  10. int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
  11. Node head = NodeUtil.generTree(arr, 0, arr.length - 1);
  12. System.out.print("morris中序遍历:");
  13. chapter.morrisInOrder(head);
  14. System.out.print("非递归中序遍历:");
  15. NodeUtil.inOrder(head);
  16. System.out.println();
  17. System.out.print("morris前序遍历:");
  18. chapter.morrisPreOrder(head);
  19. System.out.print("非递归前序遍历:");
  20. NodeUtil.preOrder(head);
  21. System.out.print("morris后序遍历:");
  22. chapter.morrisPostOrder(head);
  23. System.out.print("非递归后序遍历:");
  24. NodeUtil.postOrder(head);
  25. }
  26. }