遍历
- 遍历可以分为深度优先遍历、广度优先遍历.深度优先遍历用递归方案比较简单,广度优先遍历似乎没有很合适的递归方案,采用非递归实现简单
- 遍历有对二叉树的遍历和对多叉树的遍历
- 二叉树遍历分为先根遍历、中根遍历、后根遍历
遍历的思想
- 树是怎样的一个结构呢?每个节点都包含着它的子节点的信息,所以可以通过本节点发现它的下一个节点
- 遍历树可以分为两个操作:
- 一、遍历每一个节点
- 二、处理节点的操作,下面程序里就是handleNode方法.
- 处理节点操作在程序中的前后位置影响了是先根、中根、后根遍历
多叉树
- 节点类
/**
* 一个简单的多叉树节点类(静态内部类)
*/
static class TreeNode {
public int value = 0;
public List<TreeNode> nodeList = new ArrayList();// represent child node
public TreeNode(int value) {
this.value = value;
}
}
- 首先创建一个树
/**创建树*/
public static TreeNode initTree() {
TreeNode root = new TreeNode(0);
TreeNode one = new TreeNode(1);
TreeNode two = new TreeNode(2);
TreeNode three = new TreeNode(3);
TreeNode four = new TreeNode(4);
TreeNode five = new TreeNode(5);
TreeNode six = new TreeNode(6);
TreeNode seven = new TreeNode(7);
TreeNode eight = new TreeNode(8);
TreeNode nine = new TreeNode(9);
TreeNode ten = new TreeNode(10);
root.nodeList.add(one);
root.nodeList.add(two);
root.nodeList.add(three);
one.nodeList.add(four);
one.nodeList.add(five);
two.nodeList.add(six);
two.nodeList.add(seven);
two.nodeList.add(eight);
three.nodeList.add(nine);
three.nodeList.add(ten);
return root;
}
- 主函数
public static void main(String[] args) {
TreeNode root = initTree();
traversal_1(root);
}
- 遍历
/**先根遍历、递归遍历、深度优先遍历*/
public static void traversal(TreeNode root){
handleNode(root);
for(TreeNode node : root.nodeList){
traversal(node);
}
}
/**处理类*/
public static void handleNode(TreeNode node){
System.out.print(node.value + " ");
}
输出的结果
0 1 4 5 2 6 7 8 3 9 10
- 如果改变handleNode方法的位置,会变为后根遍历
/**后根遍历、递归遍历、深度优先遍历*/
public static void traversal(TreeNode root) {
for (TreeNode node : root.nodeList) {
traversal(node);
}
handleNode(root);
}
输出结果
4 5 1 6 7 8 2 9 10 3 0
二叉树
- 节点类
/**一个简单的二叉树类*/
static class TreeNode {
public int value = 0;
public TreeNode left;
public TreeNode right;
public TreeNode(int value, @Nullable TreeNode left, @Nullable TreeNode right) {
this.value = value;
this.left = left;
this.right = right;
}
public TreeNode(int value) {
this(value, null, null);
}
}
- 创建树
/**创建树*/
public static TreeNode initTree() {
TreeNode root = new TreeNode(0);
TreeNode one = new TreeNode(1);
TreeNode two = new TreeNode(2);
TreeNode three = new TreeNode(3);
TreeNode four = new TreeNode(4);
TreeNode five = new TreeNode(5);
TreeNode six = new TreeNode(6);
TreeNode seven = new TreeNode(7);
TreeNode eight = new TreeNode(8);
TreeNode nine = new TreeNode(9);
TreeNode ten = new TreeNode(10);
root.left = one;
root.right = two;
one.left = three;
one.right = four;
two.left = five;
two.right = six;
three.left = seven;
three.right = eight;
four.left = nine;
four.right = ten;
return root;
}
- 遍历
/**先根遍历、递归遍历、深度优先遍历*/
public static void traversal(TreeNode root) {
handleNode(root);
if(root.left != null){
traversal(root.left);
}
if (root.right != null){
traversal(root.right);
}
}
主函数不变, 输出结果:
0 1 3 7 8 4 9 10 2 5 6
- 中根遍历、后根遍历
/**中根遍历、递归遍历、深度优先遍历*/
public static void traversal(TreeNode root) {
if(root.left != null){
traversal(root.left);
}
handleNode(root)
if (root.right != null){
traversal(root.right);
}
}
/**后根遍历、递归遍历、深度优先遍历*/
public static void traversal(TreeNode root) {
if(root.left != null){
traversal(root.left);
}
if (root.right != null){
traversal(root.right);
}
handleNode(root)
}
深度优先遍历、先根遍历、栈实现.
- 中根遍历和后根遍历需要引入一些条件判断来实现.
/**
* 非递归遍历、深度优先遍历、先根遍历,用栈实现
* 先根、中跟、后根和根节点入栈的顺序有关
*/
public static void traversal(TreeNode root) {
if (root == null) return;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
TreeNode node;
while (!stack.isEmpty()) {
node = stack.pop();
handleNode(node);
if (node.right != null) stack.push(node.right);
if (node.left != null) stack.push(node.left);
}
}
输出结果:
0 1 3 7 8 4 9 10 2 5 6
广度优先遍历、队列实现、非递归遍历
- 当遍历到一个节点的时候,对节点进行操作(handleNode)之后,还有把这个节点的下一层子节点放进队列.
/**非递归遍历、广度优先遍历、队列实现*/
public static void traversal(TreeNode root) {
if (root == null) return;
Queue<TreeNode> queue = new ArrayDeque<>();
queue.offer(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll();
handleNode(node);
if (node.left != null) {
queue.offer(node.left);
}
if (node.right != null) {
queue.offer(node.right);
}
}
}