文章目录
- 1.深度优先遍历DFS
- 递归实现
- 非递归实现
- 2.广度优先遍历BFS
- 实现:
- 应用地方:Dijkstra[单源最短路径](https://baike.baidu.com/item/单源最短路径/6975204)算法和Prim[最小生成树](https://baike.baidu.com/item/最小生成树)算法和层序遍历
- 3.验证
- 1.节点类的代码
- 2.初始化树类的代码
- 3.验证----我将遍历方法写在了main()方法所在的BinaryTree类
- 4.结果
1.深度优先遍历DFS
深度优先遍历是图论中的经典算法,其利用了深度优先搜索算法可以产生目标图的相应拓扑排序表,采用拓扑排序表可以解决很多相关的图论问题,如最大路径问题等等。
深度优先搜索用栈(stack)来实现,整个过程可以想象成一个倒立的树形:
1、把根节点压入栈中。
2、每次从栈中弹出一个元素,搜索所有在它下一级的元素,把这些元素压入栈中。并把这个元素记为它下一级元素的前驱。
3、找到所要找的元素时结束程序。
4、如果遍历整个树还没有找到,结束程序。
递归实现
List<TreeNode> treeNodeList = new ArrayList<>();;
public List<TreeNode> dfsRec(TreeNode root) {
if (root == null) {
return null;
}
treeNodeList.add(root);
//System.out.print(root.value+" ");
dfsRec(root.left);
dfsRec(root.right);
return treeNodeList;
}
非递归实现
//深度优先遍历
List<TreeNode> treeList ;
public List<TreeNode> dfs(TreeNode root) {
treeList = new ArrayList<>();
if(root==null) {
return null;
}
Stack<TreeNode> myStack=new Stack<>();
myStack.add(root);
while(!myStack.isEmpty()) {
TreeNode node=myStack.pop(); //弹出栈顶元素
//System.out.print(node.value+" ");
treeList.add(node);
//向栈中先压入右子树,在压入左子树。这样出栈时,先出左子树再出右子树.也就是,先遍历左边,后遍历右边
if(node.right!=null) {
myStack.push(node.right);
}
if(node.left!=null) {
myStack.push(node.left);
}
}
return treeList;
}
2.广度优先遍历BFS
Dijkstra单源最短路径算法和Prim最小生成树算法都采用了广度优先遍历。其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。
实现:
广度优先搜索使用**队列(queue)**来实现,整个过程也可以看做一个倒立的树形:
1、把根节点放到队列的末尾。
2、每次从队列的头部取出一个元素,查看这个元素所有的下一级元素,把它们放到队列的末尾。并把这个元素记为它下一级元素的前驱。
3、找到所要找的元素时结束程序。
4、如果遍历整个树还没有找到,结束程序。 [1]
应用地方:Dijkstra单源最短路径算法和Prim最小生成树算法和层序遍历
//广度优先遍历
public List<TreeNode> bfs(TreeNode root) {
treeList = new ArrayList<>();
if(root == null){
return null;
}
Queue<TreeNode> queue = new ArrayDeque<>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode node = queue.poll(); // Java 的 pop 写作 poll()
treeList.add(node);
//System.out.print(node.value);
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
return treeList;
}
3.验证
1.节点类的代码
package tree;
public class TreeNode {
public int value;
public TreeNode leftNode;
public TreeNode rightNode;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public TreeNode getLeftNode() {
return leftNode;
}
public void setLeftNode(TreeNode leftNode) {
this.leftNode = leftNode;
}
public TreeNode getRightNode() {
return rightNode;
}
public void setRightNode(TreeNode rightNode) {
this.rightNode = rightNode;
}
public TreeNode() {
}
public TreeNode(int value) {
this.value = value;
}
}
2.初始化树类的代码
package tree;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
public class BinaryTree {
//根结点,默认为null
private TreeNode root = null;
public TreeNode getRoot() {
return root;
}
// 树的节点已经不需要按顺序排好
public void buildBinaryNode(TreeNode node,int data){
//如果根结点是空,那么设置根结点,并且设置数据域
if(root == null){
root = new TreeNode(data);
}else{
/**
* 根结点不为空,那么判断数据是否小于当前结点的数据
*/
if(data < node.getValue()){
//如果小于,判断当前结点是否有左叶子结点
if(node.getLeftNode() == null){
//左叶子结点为空,设置左叶子结点,并且设置数据
node.setLeftNode(new TreeNode(data));
}else{
//左叶子结点不为空,递归调用构建二叉树的函数
buildBinaryNode(node.getLeftNode(),data);
}
}else{
//如果大于或等于,判断当前结点是否存在右叶子结点
if(node.getRightNode()==null){
//右叶子结点为空,设置右叶子结点,并且设置数据域
node.setRightNode(new TreeNode(data));
}else{
//右叶子几点不为空,递归调用构建二叉树的函数
buildBinaryNode(node.getRightNode(),data);
}
}
}
}
public BinaryTree createBinaryTree(int[] datas){
BinaryTree binaryTree = new BinaryTree();
for (int data : datas) {
binaryTree.buildBinaryNode(binaryTree.getRoot(),data);
}
return binaryTree;
}
}
3.验证----我将遍历方法写在了main()方法所在的BinaryTree类
public static void main(String[] args) {
int[] data2 = {8,7,4,10,9,10};
BinaryTree binaryTree = new BinaryTree();
BinaryTree biTree = binaryTree.createBinaryTree(data2);
System.out.println("深度优先遍历递归版:");
List<TreeNode> treeNodeList = biTree.dfsRec(tree);
for (TreeNode treeNode : treeNodeList) {
System.out.print(treeNode.value+" ");
}
System.out.println();
System.out.println("深度优先遍历非递归版:");
List<TreeNode> treeNodes = biTree.dfs(tree);
for (TreeNode treeNode : treeNodes) {
System.out.print(treeNode.value+" ");
}
System.out.println();
System.out.println("广度优先遍历:");
List<TreeNode> bfs = biTree.bfs(tree);
for (TreeNode bf : bfs) {
System.out.print(bf.value+" ");
}
}
4.结果