一、案例
1.1 层次遍历树
思路:
- 使用队列
- 首先将树的根节点放入队列中
- 取出当前对首节点,记为poll
- 判断poll是否为空,为空,返回null,不为空,打印poll节点的值
- 判断poll的左节点是否为空,否,进队,是,不作处理
- 判断poll的右节点是否为空,否,进队,是,不作处理
- 返回第一步
public class Tree_Order {
public static void levelOrder(Node root) {
Queue<Node> queue = new LinkedList();
queue.offer(root);
while (!queue.isEmpty()) {
Node poll = queue.poll();
System.out.print(poll.value + " ");
if (poll.getLeft() != null) {
queue.offer(poll.getLeft());
}
if (poll.getRight() != null) {
queue.offer(poll.getRight());
}
}
}
}
1.2 层次遍历树-按层序输出每层节点
思路:
- last始终代表当前行的最右节点
- nlast始终代表下一行的最右节点
- 打印比遍历慢一拍
- 取出队列的头结点,计为poll
- 判断poll的左子节点是否为空,否,入队,且nlast指向该节点,是,不作处理
- 判断poll的右子节点是否为空,否,入队,且nlast指向该节点,是,不作处理
- 判断当前出队的节点是否等于last,是,打印该节点的值,并打印换行符,且last指向nlast。
- 当前出队的节点不等于last,打印该节点的值即可
- 返回第一步
public static void levelOrder1(Node root) {
Queue<Node> queue = new LinkedList<>();
queue.add(root);
Node last = root;
Node nlast = root;
while (!queue.isEmpty()) {
Node node = queue.poll();
if (node.getLeft() != null) {
queue.offer(node.getLeft());
nlast = ((LinkedList<Node>) queue).getLast();
}
if (node.getRight() != null) {
queue.offer(node.getRight());
nlast = ((LinkedList<Node>) queue).getLast();
}
if (node == last) {
System.out.print(node.getValue() + "\n");
last = nlast;
} else {
System.out.print(node.getValue() + " ");
}
}
}
1.3 二叉树的序列化
方式:
- 先序
- 中序
- 后序
- 层次遍历
思路:此次使用先序序列的方式序列化
空节点用:“#!”表示,正常节点用“数值!”
- 判断根节点是否为空,不为空,表示根节点,空,返回#!
- 判断右子节点,不为空,作为根节点,从1步骤判断,为空,用"#!"表示
- 判断左子节点,不为空,作为根节点,从1步骤判断,为空,用"#!"表示
public static void Serialize(Node root){
if(root != null){
code = code + root.getValue() + "! ";
}
if(root.getLeft() == null){
code = code + "#! ";
}
if(root.getLeft() != null)
Serialize(root.getLeft());
if(root.getRight() == null){
code = code + "#! ";
}
if(root.getRight() != null)
Serialize(root.getRight());
}
结果:
A! B! D! G! I! #! #! #! #! #! C! E! H! #! #! #! F! #! #!
1.4 二叉树的反序列化
方式:
- 先序
- 中序
- 后序
- 层次遍历
先序:
public static Node deSerialization(String Serialize){
String[] split = Serialize.split("!");
index ++;
Node node = null;
if(!split[index].equals("#")){
node = new Node(split[index]);
node.setLeft(deSerialization(Serialize));
node.setRight(deSerialization(Serialize));
}
return node;
}
二、用到的数据结构
2.1 树类
public class ManyTree {
public static Node Kind1(){
/**
* A
* / \
* / \
* B c
* / \ / \
* D E F G
* |
* H
*/
Node nodeA = new Node("A");
Node nodeB = new Node("B");
Node nodeC = new Node("C");
Node nodeD = new Node("D");
Node nodeE = new Node("E");
Node nodeF = new Node("F");
Node nodeG = new Node("G");
Node nodeH = new Node("H");
nodeA.setLeft(nodeB);
nodeA.setRight(nodeC);
nodeB.setLeft(nodeD);
nodeB.setRight(nodeE);
nodeC.setLeft(nodeF);
nodeC.setRight(nodeG);
nodeD.setLeft(nodeH);
return nodeA;
}
public static Node Kind2(){
/**
* A
* / \
* / \
* B c
* / / \
* D E F
* | |
* G H
* |
* I
*/
Node nodeA = new Node("A");
Node nodeB = new Node("B");
Node nodeC = new Node("C");
Node nodeD = new Node("D");
Node nodeE = new Node("E");
Node nodeF = new Node("F");
Node nodeG = new Node("G");
Node nodeH = new Node("H");
Node nodeI = new Node("I");
nodeA.setLeft(nodeB);
nodeA.setRight(nodeC);
nodeB.setLeft(nodeD);
nodeC.setRight(nodeF);
nodeC.setLeft(nodeE);
nodeD.setLeft(nodeG);
nodeE.setLeft(nodeH);
nodeG.setLeft(nodeI);
return nodeA;
}
}
2.2 节点
public class Node {
String value;
Node right;
Node left;
public Node(String value) {
this.value = value;
}
public Node(String value, Node right, Node left) {
this.value = value;
this.right = right;
this.left = left;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
}