剑指offerDayN树

很奇怪的一件事,明明不卷他们却说我很卷,我反驳无效搞得我很尴尬

身为一个小菜鸡每天都害怕毕业即失业。。。

package offer;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

/*
查找平衡二叉树第k小的节点
1平衡二叉树左<根<右
2 平衡二叉树的中序是递增排序 中序找第k个

中序写问题老出现重复的数值 要看debug 不然只能一遍遍看别人代码
stack.add(root); 不能再循环外写
 */
public class Test34 {
    //非递归中序存储 中序设置了一个指针
    //左根右
    public static List<Integer> inOreder(TreeNode root) {
        System.out.println("中序遍历");
        List<Integer> list = new ArrayList<Integer>();
        if (root == null) return null;
        /**
         * 中序遍历,左头右的顺序,所以要先打印出最左边的子树,我们就先一直向左找
         * 直到为空,即到最左处的时候,出栈,此时的元素就是最左边的节点,打印后,寻找
         * 它的右子树,重复上述步骤.
         */
        Stack<TreeNode> stack = new Stack<TreeNode>();
        while (!stack.isEmpty() || root != null) {
            if (root != null) {
                stack.push(root);
                root = root.left;
            } else {
                root = stack.pop();
                list.add(root.val);
                root = root.right;
            }
        }

        return list;
    }

    //用指针的形式
    public static List<Integer> inOreder2(TreeNode root) {
        //判空
        if (root == null) return null;
        Stack<TreeNode> stack = new Stack<>();
        List<Integer> list = new ArrayList<>();
        TreeNode cur = root;
        while (!stack.isEmpty() || cur != null) {
            while (cur != null) {

                stack.push(cur);
                cur = cur.left;
            }
            TreeNode node = stack.pop();
            list.add(node.val);
            if (node.right != null)
                cur = node.right;
        }
        return list;
    }


    public static void main(String[] args) {
        TreeNode treeNode = new TreeNode(5);
        treeNode.left = new TreeNode(3);
        treeNode.left.left = new TreeNode(2);
        treeNode.left.right = new TreeNode(4);
        treeNode.right = new TreeNode(7);
        treeNode.right.left = new TreeNode(6);
        treeNode.right.right = new TreeNode(8);

        List<Integer> list = inOreder2(treeNode);
        System.out.println(list);
        //第k小的数值
        System.out.println(list.get(3-1));
    }
}

数组是否为后序遍历

package offer;

/*
判断是否为二叉搜索树的后序遍历
后序 左右根 根为最后一个
左边小右边大 递归遍历
4 8 6 12 16 14 10
0 1 2  3  4  5  6
 */
public class Test35 {
    //递归判断是不是后续遍历
    //分成两段代码写
    public static boolean verifyPostorders(int[] postOrder) {
        //判断成立的条件
        if (postOrder.length <= 0 || postOrder == null) return false;
        if (postOrder.length == 1) return true;
        return same(postOrder, 0, postOrder.length - 1);
    }

    public static boolean same(int[] postOrder, int start, int end) {
        //退出递归
        if (start > end) return true;
        //最后一个节点是根节点 定义长度
        int i = end;
        //从后往前找第一个比根节点小的数值  下标3 数值6跳出
        while (i > start && postOrder[i - 1] > postOrder[end]) {
            i--;
        }
        //从前往后判断是否小于根节点 如果从前往后找到比根大的数(应该比根小的区域里)
        //已经记录下了i的值
        for (int j = start; j < i - 1; j++) {
            if (postOrder[j] > postOrder[end])
                return false;
        }
        //判断左右子树
        //数组位置 end-1 (4 8 6)( 12 16 14) 10
        return same(postOrder, start, i - 1) && same(postOrder, i, end - 1);
    }

    public static void main(String[] args) {
        int[] array = {4, 8, 6, 12, 16, 14, 10};
        System.out.println(verifyPostorders(array));
    }
}

感觉有点眉目了,写了那么久稍微能有点意思了

 根据二叉树中序遍历查找某个结点的下个结点---第二种情况不是很懂 二叉树next指针目前没用过

问了大佬疫苗解决 突然发现自己好菜好菜

package offer;

/*
根据二叉树中序遍历查找某个结点的下个结点
三种情况
1有右孩子 找到右孩子循环遍历右孩子的左节点
2 没有右孩子 而且是根的左孩子 返回父亲节点
3 是父节点的右孩子 而且没有右孩子 返回父节点的父节点
 */
class TreeNodes {
    int val;
    TreeNodes left;
    TreeNodes right;
    TreeNodes next;

    public TreeNodes(int val) {
        this.val = val;
    }

    public TreeNodes(int val, TreeNodes left, TreeNodes right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

public class Test36 {
    /**
     * 根据二叉树中序遍历查找某个结点的下个结点
     *
     * @param root
     * @return
     */
    public static TreeNodes getNextInorders(TreeNodes root) {
        //判空
        if (root == null) return null;
        //构建父节点指针
        TreeNodes cur = root;
        //指向当前指针
        //情况1 循环遍历查找右节点里面的左节点
        if (cur.right != null) {
            //一直往右走
            cur = cur.right;
            while (cur.left != null) {
                //找到最左节点
                cur = cur.left;
            }
            return cur.left;
        }
        //没有右孩子 而且是根的左孩子 返回父亲节点
        //节点的构造函数里面有父节点
        //搜索父节点 next这个关系存储了父节点
        //cur.next != null 根节点没有父节点
        while (cur.next != null) {
            if (cur.next.left == cur)
                //最后一层左边的节点 返回父节点
                return cur.next;
            //右边节点直接会父节点的节点
            cur = cur.next;
        }
        return null;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值