1. 分别用递归和非递归的方式实现二叉树先序、中序、后序遍历
package charpter3;
import java.util.Stack;
/**
* @author chengzhengda
* @version 1.0
* @date 2019-10-09 19:58
* @desc
*/
public class test1 {
// 递归前序遍历
public static void preOrder(Node head) {
if (head == null) {
return;
}
System.out.println(head.data);
preOrder(head.left);
preOrder(head.right);
}
// 非递归前序遍历
public static void preOrder1(Node head) {
if (head == null) {
return;
}
Stack<Node> stack = new Stack<>();
stack.push(head);
while (!stack.isEmpty()) {
Node temp = stack.pop();
System.out.println(temp.data);
if (temp.right != null) {
stack.push(temp.right);
}
if (temp.left != null) {
stack.push(temp.left);
}
}
}
// 非递归中序遍历
public static void midOrder1(Node head) {
Stack<Node> stack = new Stack<>();
stack.push(head);
while (!stack.isEmpty()) {
if (head != null && head.left != null) {
stack.push(head.left);
head = head.left;
} else {
head = stack.pop();
System.out.println(head.data);
if (head.right != null) {
stack.push(head.right);
head = head.right;
}
}
}
}
// 非递归后序遍历
public static void afterOrder1(Node head) {
Stack<Node> stack1 = new Stack<>();
Stack<Node> stack2 = new Stack<>();
stack1.push(head);
while (!stack1.isEmpty()) {
head = stack1.pop();
stack2.push(head);
if (head.left != null) {
stack1.push(head.left);
}
if (head.right != null) {
stack1.push(head.right);
}
}
while (!stack2.isEmpty()) {
System.out.println(stack2.pop().data);
}
}
// 递归中序遍历
public static void midOrder(Node head) {
if (head == null) {
return;
}
midOrder(head.left);
System.out.println(head.data);
midOrder(head.right);
}
// 递归后序遍历
public static void afterOrder(Node head) {
if (head == null) {
return;
}
afterOrder(head.left);
afterOrder(head.right);
System.out.println(head.data);
}
public static void main(String[] args) {
Node node1 = new Node(4);
Node node2 = new Node(2);
Node node3 = new Node(6);
Node node4 = new Node(1);
Node node5 = new Node(3);
Node node6 = new Node(5);
Node node7 = new Node(7);
node1.left = node2;
node1.right = node3;
node2.left = node4;
node2.right = node5;
node3.left = node6;
node3.right = node7;
afterOrder1(node1);
}
}
2. 打印二叉树的边界节点
题目描述:
给定一棵二叉树的头结点head,按照如下标准分别实现二叉树边界节点的逆时针打印
头结点为边界节点
叶节点为边界节点
如果节点在其所在的层中是最左或最右的,那么也是边界节点
代码:
package charpter3;
/**
* @author chengzhengda
* @version 1.0
* @date 2019-10-09 23:09
* @desc
*/
public class test2 {
public static void printedge(Node head) {
if (head == null) {
return;
}
int height = getHeight(head, 0);
Node[][] edgeMap = new Node[height][2];
setEdge(head, 0, edgeMap);
// 从上到下打印左边界
for (int i = 0; i < edgeMap.length; i++) {
System.out.println(edgeMap[i][0].data);
}
// 打印既不是左边界又不是有边界的叶子节点
printLeafNotInMap(head, 0, edgeMap);
// 从下到上打印右边界
for (int j = edgeMap.length - 1; j > 0; j--) {
System.out.println(edgeMap[j][1].data);
}
}
public static int getHeight(Node head, int l) {
if (head == null) {
return l;
}
return Math.max(getHeight(head.left, l + 1), getHeight(head.right, l + 1));
}
public static void setEdge(Node head, int l, Node[][] edgeMap) {
if (head == null) {
return;
}
edgeMap[l][0] = edgeMap[l][0] == null ? head : edgeMap[l][0];
edgeMap[l][1] = head;
setEdge(head.left, l + 1, edgeMap);
setEdge(head.right, l + 1, edgeMap);
}
public static void printLeafNotInMap(Node head, int l, Node[][] map) {
if (head == null) {
return;
}
if (head.left == null && head.right == null && head != map[l][0] && head != map[l][1]) {
System.out.println(head.data);
}
printLeafNotInMap(head.left, l + 1, map);
printLeafNotInMap(head.right, l + 1, map);
}
public static void main(String[] args) {
Node node1 = new Node(4);
Node node2 = new Node(2);
Node node3 = new Node(6);
Node node4 = new Node(1);
Node node5 = new Node(3);
Node node6 = new Node(5);
Node node7 = new Node(7);
node1.left = node2;
node1.right = node3;
node2.left = node4;
node2.right = node5;
node3.left = node6;
node3.right = node7;
printedge(node1);
}
}
3. 二叉树按层遍历
package charpter3;
import java.util.LinkedList;
/**
* @author chengzhengda
* @version 1.0
* @date 2019-10-10 18:16
* @desc
*/
public class test3 {
// 二叉树按层打印
public static void printLay(Node head) {
LinkedList<Node> queue = new LinkedList<>();
queue.offer(head);
while (!queue.isEmpty()) {
Node temp = queue.poll();
System.out.println(temp.data);
if (temp.left != null) {
queue.offer(temp.left);
}
if (temp.right != null) {
queue.offer(temp.right);
}
}
}
// 按层遍历又叫宽度优先遍历,先序遍历又叫深度优先遍历
// 按层打印二叉树并输出行号
public static void printLay2(Node head) {
LinkedList<Node> queue = new LinkedList<>();
queue.offer(head);
int level = 1;
Node last = head;
Node nLast = null;
System.out.print("Level" + (level++) + ": ");
while (!queue.isEmpty()) {
Node temp = queue.poll();
System.out.print(temp.data + " ");
if (temp.left != null) {
queue.offer(temp.left);
nLast = temp.left;
}
if (temp.right != null) {
queue.offer(temp.right);
nLast = temp.right;
}
if (last == temp && !queue.isEmpty()) {
last = nLast;
System.out.println();
System.out.print("Level" + (level++) + ": ");
}
}
}
public static void main(String[] args) {
Node node1 = new Node(4);
Node node2 = new Node(2);
Node node3 = new Node(6);
Node node4 = new Node(1);
Node node5 = new Node(3);
Node node6 = new Node(5);
Node node7 = new Node(7);
node1.left = node2;
node1.right = node3;
node2.left = node4;
node2.right = node5;
node3.left = node6;
node3.right = node7;
printLay2(node1);
}
}
4. 二叉树ZigZag打印
package charpter3;
import java.util.LinkedList;
/**
* @author chengzhengda
* @version 1.0
* @date 2019-10-10 20:38
* @desc
*/
public class test4 {
// zigzag打印二叉树
public static void printTreeVisually(Node head) {
LinkedList<Node> queue = new LinkedList<>();
queue.addFirst(head);
int level = 1;
boolean lr = true;
Node last = head;
Node nLast = null;
System.out.print("Level" + (level++) + ": ");
while (!queue.isEmpty()) {
Node temp = null;
if (lr) {
temp = queue.pollFirst();
if (temp.left != null) {
nLast = nLast == null ? temp.left : nLast;
queue.offerLast(temp.left);
}
if (temp.right != null) {
nLast = nLast == null ? temp.right : nLast;
queue.offerLast(temp.right);
}
} else {
temp = queue.pollLast();
if (temp.right != null) {
nLast = nLast == null ? temp.right : nLast;
queue.offerFirst(temp.right);
}
if (temp.left != null) {
nLast = nLast == null ? temp.left : nLast;
queue.offerFirst(temp.left);
}
}
System.out.print(temp.data + " ");
if (temp == last && !queue.isEmpty()) {
lr = !lr;
last = nLast;
nLast = null;
System.out.println();
System.out.print("Level" + (level++) + ": ");
}
}
}
public static void main(String[] args) {
Node node1 = new Node(4);
Node node2 = new Node(2);
Node node3 = new Node(6);
Node node4 = new Node(1);
Node node5 = new Node(3);
Node node6 = new Node(5);
Node node7 = new Node(7);
node1.left = node2;
node1.right = node3;
node2.left = node4;
node2.right = node5;
node3.left = node6;
node3.right = node7;
printTreeVisually(node1);
}
}
5. 调整搜索二叉树中两个错误的节点
题目描述:
一棵二叉树原本是搜索二叉树,但是其中有两个节点调换了位置,使得这棵二叉树不再是搜索二叉树,请找到这个两个错误节点并打印。
代码:
package charpter3;
import java.util.Stack;
/**
* @author chengzhengda
* @version 1.0
* @date 2019-10-11 11:04
* @desc 调整搜索二叉树中两个错误的节点
*/
public class test5 {
public static Node[] adjustErroNode(Node head) {
Node[] errs = new Node[2];
Stack<Node> stack = new Stack<>();
stack.push(head);
Node pre = null;
while (!stack.isEmpty()) {
if (head != null && head.left != null) {
stack.push(head.left);
head = head.left;
} else {
head = stack.pop();
if (pre != null && pre.data > head.data) {
errs[0] = errs[0] == null ? pre : errs[0];
errs[1] = head;
}
pre = head;
if (head.right != null) {
stack.push(head.right);
head = head.right;
}
}
}
System.out.println("错误数字1:" + errs[0].data);
System.out.println("错误数字2:" + errs[1].data);
return errs;
}
public static void main(String[] args) {
Node node1 = new Node(4);
Node node2 = new Node(5);
Node node3 = new Node(6);
Node node4 = new Node(1);
Node node5 = new Node(3);
Node node6 = new Node(2);
Node node7 = new Node(7);
node1.left = node2;
node1.right = node3;
node2.left = node4;
node2.right = node5;
node3.left = node6;
node3.right = node7;
adjustErroNode(node1);
}
}