很奇怪的一件事,明明不卷他们却说我很卷,我反驳无效搞得我很尴尬
身为一个小菜鸡每天都害怕毕业即失业。。。
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;
}
}