Java 中二叉树的广度优先搜索 (BFS) 和深度优先搜索 (DFS)

广度优先搜索 和** 深度优先搜索** 是两种遍历图和树的技术。在本教程中,我们将主要关注树中的BFS和DFS遍历。

什么是深度优先搜索?

该算法从根节点开始,然后探索backtracking.之前的每个分支它是使用堆栈实现的。在编写代码时,我们经常使用递归堆栈来回溯。通过使用递归,我们能够利用这样一个事实,即左子树和右子树也是树,并且共享相同的属性。

对于二叉树,有三种类型的DFS遍历。

1.有序 2.预购 3.后购

什么是广度优先搜索?

该算法也从根节点开始,然后逐级访问所有节点。这意味着在根之后,它将遍历根的所有直接子对象。在遍历根的所有直接子项之后,它将移动到它们的子项,依此类推。要实现BFS,我们使用队列。

对于二叉树,我们有层次顺序遍历 ,它遵循BFS。

BFS和DFS在Java中的实现

假设考虑中的树是:

二进制Tree

TreeNode类的结构如下:

1static class TreeNode {
2        int data;
3        TreeNode left, right;
4
5        public TreeNode(int key) {
6            data = key;
7            left = right = null;
8        }
9    }

1.预购遍历

在二叉树的预序遍历中,我们首先遍历根,然后遍历左子树,最后遍历右子树。我们递归地这样做是为了受益于左子树和右子树也是树这一事实。

预订单遍历的算法如下:

1.遍历根。 2.在左子树上调用preorder()。 3.在右子树上调用preorder()。

上述树的预购遍历为:

10 1 3 4 2

Java代码如下:

 1static void preorder(TreeNode TreeNode) {
 2        if (TreeNode == null)
 3            return;
 4
 5        // Traverse root
 6        System.out.print(TreeNode.item + "->");
 7        // Traverse left
 8        preorder(TreeNode.left);
 9        // Traverse right
10        preorder(TreeNode.right);
11    }

2.有序遍历

二叉树的按序遍历首先遍历左子树,然后是根,最后是右子树。

有序遍历的算法如下:

1.对左子树调用inorder()。 2.遍历根。 3.对右子树调用inorder()。

上面树的顺序遍历是:

13 1 4 0 2

Java代码如下:

 1static void inorder(TreeNode TreeNode) {
 2        if (TreeNode == null)
 3            return;
 4
 5        // Traverse left
 6        inorder(TreeNode.left);
 7        // Traverse root
 8        System.out.print(TreeNode.item + "->");
 9        // Traverse right
10        inorder(TreeNode.right);
11    }

3.订单后遍历

二叉树的后序遍历首先遍历左子树,然后遍历右子树,最后遍历根。

后序遍历的算法如下:

1.在左子树上调用postorder()。 2.对右子树调用postorder()。 3.遍历根。

上面树的后序遍历是:

13 4 1 2 0

Java代码如下:

 1static void postorder(TreeNode TreeNode) {
 2        if (TreeNode == null)
 3            return;
 4
 5        // Traverse left
 6        postorder(TreeNode.left);
 7        // Traverse right
 8        postorder(TreeNode.right);
 9        // Traverse root
10        System.out.print(TreeNode.item + "->");
11    }

4.层次顺序遍历

层次顺序遍历使用队列来跟踪要访问的节点。访问一个节点后,它的子节点被放入队列中。为了得到一个新的节点来遍历,我们从队列中取出元素。

算法如下:

1.初始化空队列 2.从将temp设置为根开始 3.运行循环,直到队列不为空 1.从临时打印数据。 2.按从左到右的顺序排列临时员工的子项。 3.使节点从队列中退出队列,并将其值赋给Temp。

上述树的级别顺序遍历为:

10 1 2 3 4

Java代码如下:

 1static void printLevelOrder(TreeNode root) {
 2       Queue<TreeNode> queue = new LinkedList<TreeNode>();
 3       queue.add(root);
 4       while (!queue.isEmpty()) {
 5           TreeNode temp = queue.poll();
 6           System.out.print(temp.data + " ");
 7
 8           /*add left child to the queue */
 9           if (temp.left != null) {
10               queue.add(temp.left);
11           }
12
13           /*add right right child to the queue */
14           if (temp.right != null) {
15               queue.add(temp.right);
16           }
17       }
18   }

用Java完成BFS和DFS的代码实现

完整的Java代码如下所示:

 1package com.JournalDev;
 2import java.util.LinkedList;
 3import java.util.Queue;
 4
 5public class Main {
 6    static class TreeNode {
 7        int data;
 8        TreeNode left, right;
 9
10        public TreeNode(int key) {
11            data = key;
12            left = right = null;
13        }
14    }
15
16    static void preorder(TreeNode TreeNode) {
17        if (TreeNode == null)
18            return;
19
20        // Traverse root
21        System.out.print(TreeNode.data + " ");
22        // Traverse left
23        preorder(TreeNode.left);
24        // Traverse right
25        preorder(TreeNode.right);
26    }
27
28    static void inorder(TreeNode TreeNode) {
29        if (TreeNode == null)
30            return;
31
32        // Traverse left
33        inorder(TreeNode.left);
34        // Traverse root
35        System.out.print(TreeNode.data + " ");
36        // Traverse right
37        inorder(TreeNode.right);
38    }
39
40    static void postorder(TreeNode TreeNode) {
41        if (TreeNode == null)
42            return;
43
44        // Traverse left
45        postorder(TreeNode.left);
46        // Traverse right
47        postorder(TreeNode.right);
48        // Traverse root
49        System.out.print(TreeNode.data + " ");
50    }
51   static void printLevelOrder(TreeNode root) {
52       Queue<TreeNode> queue = new LinkedList<TreeNode>();
53       queue.add(root);
54       while (!queue.isEmpty()) {
55           TreeNode tempNode = queue.poll();
56           System.out.print(tempNode.data + " ");
57
58           /*add left child to the queue */
59           if (tempNode.left != null) {
60               queue.add(tempNode.left);
61           }
62
63           /*add right right child to the queue */
64           if (tempNode.right != null) {
65               queue.add(tempNode.right);
66           }
67       }
68   }
69
70    public static void main(String args[])
71
72    {
73        TreeNode root = new TreeNode(0);
74        root.left = new TreeNode(1);
75        root.right = new TreeNode(2);
76        root.left.left = new TreeNode(3);
77        root.left.right = new TreeNode(4);
78        System.out.println("Inorder traversal");
79        inorder(root);
80
81        System.out.println("\nPreorder traversal ");
82        preorder(root);
83
84        System.out.println("\nPostorder traversal");
85       postorder(root);
86
87        System.out.println("\nLevelorder traversal");
88        printLevelOrder(root);
89
90    }
91
92}
 1Output : 
 2
 3Inorder traversal
 43 1 4 0 2 
 5Preorder traversal 
 60 1 3 4 2 
 7Postorder traversal
 83 4 1 2 0 
 9Levelorder traversal
100 1 2 3 4

树Traversal

结论

本教程介绍的是二叉树中的BFS和DFS遍历。要获得C++中的DFS实现,请参阅此tutorial.有关级别顺序遍历的C++实现,请参阅此tutorial.

Published At
Categories with 技术
comments powered by Disqus