深度优先搜素 DFS 递归方式和非递归方式实现

package pro;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;

public class DFS {
    private static int INF = 100; // 点的最大个数
    // 邻接链表,存储边的变量容器
    private static ArrayList<Integer>[] arrayLists = new ArrayList[INF];
    // 控制访问的标记变量
    private static boolean[] visited = new boolean[INF];

    // 传统递归的深度优先搜素
    // 递归遍历
    private static void dfs(int cur) {
        visited[cur] = true; // 访问到置为true
        for (int i = 0; i < arrayLists[cur].size(); i++) {
            //寻找下一个没有访问的连接的点。
            if(!visited[arrayLists[cur].get(i)]) {
                System.out.print(arrayLists[cur].get(i)+" ");
                dfs(arrayLists[cur].get(i));
                //回溯了继续循环寻找兄弟节点没有访问的连接的点
            }
        }
    }

    // 不用递归实现深度优先搜素。模仿stack的方式实现
    // 因为Stack的线程安全所以用LinkedList代替效率会好一些
    private static LinkedList<int[]> linkedList = new LinkedList<>();

    private static void dfs_stack(int start) {
        int order = -1, i;
        //初始化遍历值
        Arrays.fill(visited, false);
        linkedList.clear();
        
        visited[start] = true;
        // 每次添加元素从最后加入
        linkedList.addLast(new int[]{start, -1});
        
        while (!linkedList.isEmpty()) {
            int cur = linkedList.getLast()[0];

            for (i = order+1; i < arrayLists[cur].size(); i++) {
                int next = arrayLists[cur].get(i);
                if(!visited[next]) {
                    visited[next] = true;
                    System.out.print(next+" ");
                    linkedList.addLast(new int[]{next, i});
                    order = -1;
                    break;
                }
            }

            // 没有找到能连接的点时。回退上一个点的order
            if (i == arrayLists[cur].size()){
                order = linkedList.removeLast()[1];
            }
        }
    }

    public static void main(String[] args) {
        // 构建边
        for (int i = 0; i < 11; i++) {
            arrayLists[i] = new ArrayList<>();
        }
        arrayLists[1].add(2);
        arrayLists[1].add(3);
        arrayLists[2].add(4);
        arrayLists[2].add(5);
        arrayLists[3].add(6);
        arrayLists[3].add(7);
        arrayLists[4].add(8);
        arrayLists[4].add(9);
        arrayLists[5].add(10);
        arrayLists[2].add(1);
        arrayLists[3].add(1);
        arrayLists[4].add(2);
        arrayLists[5].add(2);
        arrayLists[6].add(3);
        arrayLists[7].add(3);
        arrayLists[8].add(4);
        arrayLists[9].add(4);
        arrayLists[10].add(5);

        dfs(1);
        System.out.println();
        dfs_stack(1);
    }
}

 

posted @ 2020-11-03 09:56  姓蜀名黍  阅读(207)  评论(0)    收藏  举报