二叉树的建立

public class TreeNode {

    public TreeNode left;
    public TreeNode right;
    public int value;
    public TreeNode next;
}
public class 二叉树的建立 {

    private static int counter = 0;//定义一个静态计数变量

    public static void main(String[] args) {
        int[] a = {1, 2, 3, 0, 0, 4, 0, 0, 5, 0, 0};
        createBiTree(a);
    }

    public static TreeNode createBiTree(int[] a) {
        TreeNode root = new TreeNode();
        createBiTree(root, a, counter);
        return root;
    }

    /**
     * 构造二叉树
     *
     * @param root 根节点
     * @param a    数据源
     * @param i    计数器
     * @return 根节点
     */
    private static TreeNode createBiTree(TreeNode root, int[] a, int i) {
        if (i < a.length) {
            if (a[i] == 0) {
                root = null;
            } else {
                TreeNode left = new TreeNode();
                TreeNode right = new TreeNode();
                root.left = createBiTree(left, a, ++counter);
                root.right = createBiTree(right, a, ++counter);
                root.value = a[i];
            }
        }
        return root;
    }
}

建立二叉树,利用了递归的原理,也就是在打印二叉树的前中后序遍历算法中打印结点的地方,改成了生成结点,给结点赋值的操作而已。

二叉树的遍历

二叉树前中后序遍历

public class 二叉树前中后遍历 {

    static void recursionPreoderTree(TreeNode root) {
        if (root == null) {
            return;
        }
        System.out.print(root.value + " ");
        recursionPreoderTree(root.left);
        recursionPreoderTree(root.right);
    }

    static void recursionInoderTree(TreeNode root) {
        if (root == null) {
            return;
        }
        recursionInoderTree(root.left);
        System.out.print(root.value + " ");
        recursionInoderTree(root.right);
    }

    static void recursionPostorderTree(TreeNode root) {
        if (root == null) {
            return;
        }
        recursionPostorderTree(root.left);
        recursionPostorderTree(root.right);
        System.out.print(root.value + " ");
    }

    public static void main(String[] args) {
        int[] a = {1, 2, 0, 4, 0, 0, 3, 0, 0};
        TreeNode root = 二叉树的建立.createBiTree(a);
        recursionPreoderTree(root);
        System.out.println();
        recursionInoderTree(root);
        System.out.println();
        recursionPostorderTree(root);
    }
}

二叉树层序遍历(广度优先)

public class 二叉树层序遍历 {

    static void levelOrder(TreeNode root) {
        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.add(root);

        while (!queue.isEmpty()) {
            TreeNode current = queue.poll();

            System.out.print(current.value + " ");
            if (current.left != null) {
                queue.add(current.left);
            }
            if (current.right != null) {
                queue.add(current.right);
            }
        }
    }

    public static void main(String[] args) {
        int[] a = {1, 2, 0, 4, 0, 0, 3, 0, 0};
        TreeNode root = 二叉树的建立.createBiTree(a);
        levelOrder(root);
    }
}

用队列,每次遍历当前节点的时候,把该节点从队列拿出来,并且把它的子节点全部加入到队列中

题目

设置二叉树的next节点

public class 二叉树的next结点 {

    static void nextSiblings(TreeNode treeNode) {

        Queue<TreeNode> queue = new LinkedList<TreeNode>();
        queue.add(treeNode);

        //这个level没有实际用处,但是可以告诉大家怎么判断当前node是第几层。
        int level = 0;
        while (!queue.isEmpty()) {
            int size = queue.size();
            for (int i = 0; i < size; i++) {

                TreeNode current = queue.poll();
                System.out.print(current.value + " ");

                if (current.left != null) {
                    queue.offer(current.left);
                }
                if (current.right != null) {
                    queue.offer(current.right);
                }

                if (i != size - 1) {
                    current.next = queue.peek();
                }
            }
            level++;
        }
    }

    public static void main(String[] args) {
        int[] a = {1, 2, 0, 4, 0, 0, 3, 0, 0};
        TreeNode root = 二叉树的建立.createBiTree(a);
        nextSiblings(root);
    }
}

其实这个题目就是典型的层序遍历,使用队列就可以轻松解决,每次poll出来一个节点,判断是不是当前层的最后一个,如果不是,把其next设置成queue中的下一个节点就ok了。至于怎么判断当前节点是哪一层呢?使用当前queue的size做for循环。

翻转二叉树

public class 翻转二叉树 {

    static TreeNode reverseBinaryTree(TreeNode root) {
        if (root == null) {
            return null;
        } else {
            //左子树已翻转好
            TreeNode left = reverseBinaryTree(root.left);
            //右子树已翻转好
            TreeNode right = reverseBinaryTree(root.right);
            //交换左右子树
            root.right = left;
            root.left = right;
            return root;
        }
    }

}

分而治之 和 递归 的思想

铺平二叉树

public class 铺平二叉树_链表 {

    static TreeNode inflateBinaryTree(TreeNode root) {

        if (root == null) {
            return root;
        }

        //用递归的思想,把左右先铺平
        TreeNode left = inflateBinaryTree(root.left);
        TreeNode right = inflateBinaryTree(root.right);

        //把左指针和右指针先指向空。
        root.left = null;
        root.right = null;

        //假如左子树生成的链表为空,那么忽略它,把右子树生成的链表指向根节点的右指针
        if (left == null) {
            root.right = right;
            return root;
        }

        //如果左子树生成链表不为空,那么用while循环获取最后一个节点,并且它的右指针要指向右子树生成的链表的头节点
        root.right = left;
        TreeNode lastLeft = left;
        while (lastLeft.right != null) {
            lastLeft = lastLeft.right;
        }
        lastLeft.right = right;
        return root;
    }

    public static void main(String[] args) {
        int[] a = {1, 2, 0, 4, 0, 0, 3, 0, 0};
        TreeNode root = 二叉树的建立.createBiTree(a);
        inflateBinaryTree(root);
    }

}

android的findViewById

View searchViewById(ViewGroup viewGroup, int id) {

        if (viewGroup == null) {
            return null;
        }

        int childCount = viewGroup.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View view = viewGroup.getChildAt(i);
            if (view.getId() == id) {
                return view;
            }

            if (view instanceof ViewGroup) {
                View temp = searchViewById((ViewGroup) view, id);
                if (temp != null) {
                    return temp;
                }
            }
        }
        return null;
    }

线索二叉树

中序线索化二叉树

public class 中序线索化二叉树 {

    private Node preNode;   //线索化时记录前一个节点

    //节点存储结构
    static class Node {
        String data;        //数据域
        Node left;          //左指针域
        Node right;         //右指针域
        boolean isLeftThread = false;   //左指针域类型  false:指向子节点、true:前驱或后继线索
        boolean isRightThread = false;  //右指针域类型  false:指向子节点、true:前驱或后继线索

        Node(String data) {
            this.data = data;
        }
    }

    /**
     * 通过数组构造一个二叉树(完全二叉树)
     *
     * @param array
     * @param index
     * @return
     */
    static Node createBinaryTree(String[] array, int index) {
        Node node = null;

        if (index < array.length) {
            node = new Node(array[index]);
            node.left = createBinaryTree(array, index * 2 + 1);
            node.right = createBinaryTree(array, index * 2 + 2);
        }

        return node;
    }

    public static void main(String[] args) {
        String[] array = {"A", "B", "C", "D", "E", "F", "G", "H"};
        Node root = createBinaryTree(array, 0);

        中序线索化二叉树 tree = new 中序线索化二叉树();
        tree.inThreadOrder(root);
    }

    private void inThreadOrder(Node root) {

        inThreadOrder(root.left);

        //左指针为空,将指针指向刚才访问过的结点
        //若preNode为null,则当前结点时第一个结点
        if (root.left == null) {
            root.isLeftThread = true;
            root.left = preNode;
        }

        // 前一个结点的后继结点指向当前结点
        // 当前结点的后继点只能由父节点指定
        if (preNode != null && preNode.right == null) {
            preNode.isRightThread = true;
            preNode.right = root;
        }

        preNode = root;

        inThreadOrder(root.right);

    }

}

和二叉树中序遍历的递归代码几乎完全一样。只不过将本是打印的结点的功能改成了线索化的功能。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容