左程云基础班——二叉树
1. 遍历二叉树
二叉树结点:
public class Node {
public int value;
public Node left;
public Node right;
public Node(int value) {
this.value = value;
}
}
1)前序遍历
public static void preOrderRecur(Node head) {
if (head == null) {
return;
}
System.out.print(head.value + " ");
preOrderRecur(head.left);
preOrderRecur(head.right);
}
public static void preOrderUnRecur(Node head) {
if (head != null) {
Stack<Node> stack = new Stack<>();
stack.push(head);
while (!stack.isEmpty()) {
head = stack.pop();
System.out.print(head.value + " ");
if (head.right != null) {
stack.push(head.right);
}
if (head.left != null) {
stack.push(head.left);
}
}
}
}
2)后序遍历
public static void postOrderRecur(Node head) {
if (head == null) {
return;
}
postOrderRecur(head.left);
postOrderRecur(head.right);
System.out.print(head.value + " ");
}
public static void postOrderUnRrecur(Node head) {
if (head != null) {
Stack<Node> stack = new Stack<>();
Stack<Node> res = new Stack<>();
stack.push(head);
while (!stack.isEmpty()) {
head = stack.pop();
res.push(head);
if (head.left != null) {
stack.push(head.left);
}
if (head.right != null) {
stack.push(head.right);
}
}
while (!res.isEmpty()) {
System.out.print(res.pop().value + " ");
}
}
}
3)中序遍历
public static void inOrderRecur(Node head) {
if (head == null) {
return;
}
inOrderRecur(head.left);
System.out.print(head.value + " ");
inOrderRecur(head.right);
}
public static void inOrderUnRecur(Node head) {
if (head != null) {
Stack<Node> stack = new Stack<>();
while (!stack.isEmpty() || head != null) {
if (head != null) {
stack.push(head);
head = head.left;
} else {
head = stack.pop();
System.out.print(head.value + " ");
head = head.right;
}
}
}
}
4)宽度遍历(最大宽度)
public static int WildTravel(Node head) {
if (head != null) {
LinkedList<Node> queue = new LinkedList<>();
HashMap hashMap = new HashMap<Node, Integer>();
hashMap.put(head, 1);
int curlevel = 0;
int levelNodes = 0;
int maxNodes = 0;
queue.add(head);
while (!queue.isEmpty()) {
head = queue.poll();
if ((int)hashMap.get(head) > curlevel) {
curlevel = (int)hashMap.get(head);
levelNodes = 1;
}
else {
levelNodes++;
}
maxNodes = Math.max(maxNodes, levelNodes);
if (head.left != null) {
hashMap.put(head.left, (int)hashMap.get(head) + 1);
queue.add(head.left);
}
if (head.right != null) {
hashMap.put(head.right, (int)hashMap.get(head) + 1);
queue.add(head.right);
}
}
return maxNodes;
}
return 0;
}
2. 判断树结构
树形DP的套路方法:
1)判断二叉查找树
递归实现:
public static int preValue = Integer.MIN_VALUE;
public static boolean checkBST1(Node head) {
if (head == null) {
return true;
}
boolean left = checkBST1(head.left);
if (left != true) {
return false;
}
if (head.value < preValue) {
return false;
}
else {
preValue = head.value;
}
return checkBST1(head.right);
}
非递归实现:
public static boolean checkBST2(Node head) {
if (head != null) {
int preValue = Integer.MIN_VALUE;
Stack<Node> stack = new Stack<>();
while (!stack.isEmpty() || head != null) {
if (head != null) {
stack.push(head);
head = head.left;
} else {
head = stack.pop();
if (head.value < preValue) {
return false;
}
else {
preValue = head.value;
}
head = head.right;
}
}
}
return true;
}
套路实现:
public static boolean checkBST3(Node head) {
bData avData = chBST(head);
return avData.isBST;
}
private static class bData {
public boolean isBST;
public int max;
public int min;
public bData(boolean isBST, int max, int min) {
this.isBST = isBST;
this.max = max;
this.min = min;
}
}
public static bData chBST(Node head) {
if (head == null) {
return null;
}
bData left = chBST(head.left);
bData right = chBST(head.right);
int min = head.value;
int max = head.value;
if (left != null) {
min = Math.min(min, left.min);
max = Math.max(max, left.max);
}
if (right != null) {
min = Math.min(min, right.min);
max = Math.max(max, right.max);
}
boolean isBST = true;
if (left != null && (!left.isBST || left.min > head.value)) {
isBST = false;
}
if (right != null && (!right.isBST || right.max < head.value)) {
isBST = false;
}
return new bData(isBST, max, min);
}
2). 判断完全二叉树
public static boolean checkCBT(Node head) {
if (head != null) {
boolean leaf = false;
LinkedList<Node> queue = new LinkedList<>();
queue.add(head);
while (!queue.isEmpty()) {
head = queue.poll();
if (
(head.left == null && head.right != null)
|| (leaf == true && (head.left != null || head.right != null))
) {
return false;
}
if (head.left != null) {
queue.add(head.left);
}
if (head.right != null) {
queue.add(head.right);
}
else {
leaf = true;
}
}
}
return true;
}
3). 判断满二叉树
public static boolean checkFBT(Node head) {
fData c = prosses(head);
if (c.nodes == (1 << c.height) - 1)
return true;
else
return false;
}
private static class fData{
public int height;
public int nodes;
public fData(int height, int nodes) {
this.height = height;
this.nodes = nodes;
}
}
public static fData prosses(Node head) {
if (head == null) {
return new fData(0,0);
}
fData leftData = prosses(head.left);
fData rightData = prosses(head.right);
int height = Math.max(leftData.height, rightData.height) + 1;
int nodes = leftData.nodes + rightData.nodes + 1;
return new fData(height, nodes);
}
3. 练习题
1). 寻找最近的公共父节点
public static Node seekRoot(Node head, Node o1, Node o2) {
HashMap<Node, Node> root = new HashMap<>();
root.put(head, head);
storeRoot(head, root);
HashSet<Node> set = new HashSet<>();
Node cur = o1;
while (cur != head) {
set.add(cur);
cur = root.get(cur);
}
cur = o2;
while (cur != head) {
if (set.contains(cur)) {
return cur;
}
cur = root.get(cur);
}
return head;
}
public static void storeRoot(Node head, HashMap<Node, Node> root) {
if (head == null) {
return;
}
root.put(head.left, head);
root.put(head.right, head);
storeRoot(head.left, root);
storeRoot(head.right, root);
}
2). 微软折纸面试题
public static void paperFolding(int N) {
printPaper(1, N, true);
}
private static void printPaper(int i, int N, boolean f) {
if (i > N) {
return;
}
printPaper(i + 1, N, true);
String s = f == true ? "凹" : "凸";
System.out.print(s + " ");
printPaper(i + 1, N, false);
}
3). 序列化与反序列化(左神代码)
public static String serializeBT(Node head) {
if (head == null) {
return "#_";
}
String res = head.value + "_";
res += serializeBT(head.left);
res += serializeBT(head.right);
return res;
}
public static Node deserializeBT(String res) {
LinkedList<String> strings = stringsToQueue(res);
Node node = deserialzeProcess(strings);
return node;
}
private static LinkedList<String> stringsToQueue(String s) {
String[] strs = s.split("_");
LinkedList<String> queue = new LinkedList<>();
for (String s1 : strs) {
queue.add(s1);
}
return queue;
}
private static Node deserialzeProcess(LinkedList<String> queue) {
String value = queue.poll();
if (value.equals("#")) {
return null;
}
Node node = new Node(Integer.valueOf(value));
node.left = deserialzeProcess(queue);
node.right = deserialzeProcess(queue);
return node;
}