《程序员代码面试指南》第三章 二叉树问题 遍历二叉树的神级方法 morris

news/2024/7/8 6:56:51

题目

遍历二叉树的神级方法 morris

java代码

package com.lizhouwei.chapter3;

/**
 * @Description:遍历二叉树的神级方法 morris
 * @Author: lizhouwei
 * @CreateDate: 2018/4/14 17:15
 * @Modify by:
 * @ModifyDate:
 */
public class Chapter3_5 {
    //morris中序
    public void morrisInOrder(Node head) {
        Node cur1 = head;
        Node cur2 = null;//左子节点
        while (cur1 != null) {
            cur2 = cur1.left;//当前节点的左子节点
            if (cur2 != null) {
                //循环遍历到左子节点的最右子节点
                while (cur2.right != null && cur2.right != cur1) {
                    cur2 = cur2.right;
                }
                //如过最右节点未指向cur1,则使之指向cur1,并略过后续代码;
                if (cur2.right == null) {
                    cur2.right = cur1;
                    cur1 = cur1.left;
                    continue;
                } else {
                    //如过最右节点已指向cur1,恢复,则使之指向null,
                    cur2.right = null;
                }
            }
            //如果cur1.left 为null,则说明没有左子树,则开始打印父节点;
            System.out.print(cur1.value + " ");
            cur1 = cur1.right;
        }
        System.out.println();
    }

    //morris前序
    public void morrisPreOrder(Node head) {
        Node cur1 = head;
        Node cur2 = null;//左子节点
        while (cur1 != null) {
            cur2 = cur1.left;//当前节点的左子节点
            if (cur2 != null) {
                //循环遍历到左子节点的最右子节点
                while (cur2.right != null && cur2.right != cur1) {
                    cur2 = cur2.right;
                }
                //如过最右节点未指向cur1,则使之指向cur1,并略过后续代码;
                if (cur2.right == null) {
                    cur2.right = cur1;
                    System.out.print(cur1.value + " ");//遇见父节点,先打印父节点
                    cur1 = cur1.left;
                    continue;
                } else {
                    //如过最右节点已指向cur1,恢复,则使之指向null,
                    cur2.right = null;
                }
            } else {
                //如果cur1.left 为null,说明没有左子节点,在切换到右子树之前先打印父节点
                System.out.print(cur1.value + " ");
            }
            cur1 = cur1.right;
        }
        System.out.println();
    }

    //morris后序
    public void morrisPostOrder(Node head) {
        Node cur1 = head;
        Node cur2 = null;//左子节点
        while (cur1 != null) {
            cur2 = cur1.left;//当前节点的左子节点
            if (cur2 != null) {
                //循环遍历到左子节点的最右子节点
                while (cur2.right != null && cur2.right != cur1) {
                    cur2 = cur2.right;
                }
                //如过最右节点未指向cur1,则使之指向cur1,并略过后续代码;
                if (cur2.right == null) {
                    cur2.right = cur1;
                    cur1 = cur1.left;
                    continue;
                } else {
                    //如过最右节点已指向cur1,恢复,则使之指向null,
                    cur2.right = null;
                    printEdge(cur1.left);
                }
            }
            cur1 = cur1.right;
        }
        printEdge(head);
        System.out.println();
    }

    //打印节点
    public void printEdge(Node head) {
        Node tail = reverse(head);
        Node cur = tail;
        while (cur != null) {
            System.out.print(cur.value + " ");
            cur = cur.right;
        }
        //恢复链表
        reverse(tail);
    }

    //反转节点的右子节点链
    public Node reverse(Node head) {
        Node pre = null;
        Node next = null;
        while (head != null) {
            next = head.right;
            head.right = pre;
            pre = head;
            head = next;
        }
        return pre;
    }

    //测试
    public static void main(String[] args) {
        Chapter3_5 chapter = new Chapter3_5();
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        Node head = NodeUtil.generTree(arr, 0, arr.length - 1);
        System.out.print("morris中序遍历:");
        chapter.morrisInOrder(head);
        System.out.print("非递归中序遍历:");
        NodeUtil.inOrder(head);
        System.out.println();
        System.out.print("morris前序遍历:");
        chapter.morrisPreOrder(head);
        System.out.print("非递归前序遍历:");
        NodeUtil.preOrder(head);
        System.out.print("morris后序遍历:");
        chapter.morrisPostOrder(head);
        System.out.print("非递归后序遍历:");
        NodeUtil.postOrder(head);
    }
}

转载于:https://www.cnblogs.com/lizhouwei/p/8833456.html


http://www.niftyadmin.cn/n/1998582.html

相关文章

计算机基础知识2001年版本,《2001年计算机应用基础》.pdf

全国高等教育自学考试标准预测试卷2001 年计算机应用基础学苑出版社全国高等教育自学考试2001 年计算机应用基础试卷及答案(考试时间 分钟)150题 号 一 二 三 四 五 总 分题 分 40 10 30 9 11 核分人得 分 复查人第一部分 选择题40 1 40一、单项选择题(本大题共 小题&#xff0…

JavaScript and Ruby in ABAP

Netweaver里有个mini JavaScript engine CL_JAVA_SCRIPT, 对于Js code的编译和执行都是用system call完成。 只能当玩具用:report SJSEU 执行结果:120 在SAP C4C的UI Designer里,event handler里可以写Ruby Script, UI保存时Ruby Script会自动…

对银广厦事件的思考

对银广厦事件的思考     经过《财经》杂志的曝光,美丽的银广厦泡沫终于破灭了。一时之间,银广厦事件成为市场关注的焦点。有人在进一步揭露银广厦事件内幕的,有人在阐述银广厦事件对股市的影响,有人建议对银广厦事件严肃查处&…

实践所学计算机知识应用,大学计算机实践课总结报告

大学计算机实践课总结报告眨眼一个学期过了,在这一学期中学到了很多关于计算机的知识及应用,收获颇丰,虽然之前对于这些都有接触和了解,但通过学习才知道自己了解的还是太少了,只有通过学习才能知道自己的不足&#xf…

vue 开发系列(三) vue 组件开发

概要 vue 的一个特点是进行组件开发,组件的优势是我们可以封装自己的控件,实现重用,比如我们在平台中封装了自己的附件控件,输入控件等。 组件的开发 在vue 中一个组件,就是一个独立的.vue 文件,这个文件分…

林觉民·与妻书

意映卿卿如晤:  吾今以此书与汝永别矣!吾作此书时,尚为世中一人;汝看此书时,吾已成为阴间一鬼。吾作此书,泪珠和笔墨齐下,不能书竟,而欲搁笔。又恐汝不察吾衷,谓吾忍舍…

台式计算机睡眠后无法唤醒,电脑休眠后无法唤醒怎么办 电脑休眠后无法唤醒原因及解决方法...

电脑休眠后无法唤醒怎么办?在使用休眠模式时,你可以关闭计算机,并确信在回来时所有工作都会完全精确地还原到离开时的状态。内存中的内容会保存在磁盘上,监视器和硬盘会关闭,同时也节省了电能,降低了计算机的损耗。但…

mooc-IDEA 编写高质量代码--009

十五、IntelliJ IDEA -编写高质量代码 1、重构 【1】重构变量 选中某个变量,按住 shiftF6,修改变量名,则所有该变量名均会被重构为新变量名 【2】重构方法【ctrlF6 | Refactor->change signature】 重构方法 Refactor 上述也可以应用AltEn…