DFS

图的深度优先搜索
描述:
图的深度优先搜索类似于树的先根遍历,是树的先根遍历的推广。即从某个结点开始,先访问该结点,然后深度访问该结点的第一棵子树,依次为第二顶子树。如此进行下去,直到所有的结点都访问为止。在该题中,假定所有的结点以“A”至“Z”中的若干字符表示,且要求结点的访问顺序根据“A”至“Z”的字典顺序进行访问。例如有如下图:


如果要求从H开始进行深度优先搜索,则搜索结果为:H->A->K->U->E.
输入:
输入只包含一个测试用例,第一行为一个自然数n,表示顶点的个数,第二行为n个大写字母构成的字符串,表示顶点,接下来是为一个n*n大小的矩阵,表示图的邻接关系。数字为0表示不邻接,否则为相应的边的长度。
最后一行为一个字符,表示要求进行深度优先搜索的起始顶点。
输出:
用一行输出深度优先搜索结果,起始点为给定的顶点,各顶点之间用一个空格隔开。要求同一层顶点的邻接点的访问顺序按“A”至“Z”的字典顺序。
样例输入:
5
HUEAK
0 0 2 3 0
0 0 0 7 4
2 0 0 0 0
3 7 0 0 1
0 4 0 1 0
H
样例输出:
H A K U E

算法提示:首先根据图的邻接矩阵创建邻接表(采用后插法,即每个边结点都插入到最后一个位置),然后结合栈结构完成图的深度优先遍历

 

代码如下

package Graph2;
/**
5
HUEAK
0 0 2 3 0
0 0 0 7 4
2 0 0 0 0
3 7 0 0 1
0 4 0 1 0
H
@author 邹龄晋
 */
import java.util.Scanner;



//DFS用栈实现

public class DFSTest {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int z = sc.nextInt();
        String str = sc.next();
        int n =str.length();
        int e;
        Graph zg = new Graph(str);
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                e = sc.nextInt();
                if(e!=0){
                    EdgeNode p = new EdgeNode(j,e);
                    zg.insertR(i, p);
                }
            }
        }
        //看效果
//        System.out.println();
//        zg.printG();
        String c = sc.nextLine();
        c = sc.nextLine();
        int start = 0;
        for (int i = 0; i < n; i++) {
            if (str.charAt(i) == c.charAt(0)) {
                start = i;
                break;
            }
        }
        zg.DFS(start);
    
    }

}

//
class Graph {
    private int n;
    private HeadNode head[];

    public Graph() {
    }

    public Graph(String str) {
        this.n = str.length();
        head = new HeadNode[n];
        for (int i = 0; i < n; i++) {
            head[i] = new HeadNode(str.charAt(i));
        }
    }

    /**
     * 插入方法有以下三种 
     * 1.头插法 p->sn->s(n-1)->....->s2->s1
     * 2.尾插法p->s1->s2->.....->s(n-1)->sn 
     * 3.字典顺序插法
     */
    //1.头插法
    public void insertH(int i,EdgeNode p){
        p.setNext(head[i].getFirst());
        head[i].setFirst(p);
    }
    //2.尾插法
    public void insertR(int i, EdgeNode p){
        if(head[i].getFirst()==null){
            head[i].setFirst(p);
        }else{
            EdgeNode e = head[i].getFirst();
            while(e.getNext()!=null){
                e = e.getNext();
            }
            e.setNext(p);
        }
        
    }
    // 3.插入方法要求:按字典顺序插入
    public void insert(int i, EdgeNode p) {
        // 1.第一种情况,若头结点后面为null,直接将边结点插入到后面
        if (head[i].getFirst() == null) {
            head[i].setFirst(p);
            return;
        }
        // 2.第二种情况('B'<'C')前面为新插入的点
        if (head[p.getData()].getCh() < head[head[i].getFirst().getData()]
                .getCh()) {
            p.setNext(head[i].getFirst());
            head[i].setFirst(p);
            return;
        }
        // 3.第三种情况('D'>'C')
        EdgeNode e = head[i].getFirst();
        while (e.getNext() != null
                && head[p.getData()].getCh() > head[e.getData()].getCh()) {
            e = e.getNext();
        }
        if (e.getNext() != null)
            p.setNext(e.getNext());
        e.setNext(p);
    }
    // 输出图
    public void printG() {
        for (int i = 0; i < n; i++) {
            System.out.print(head[i].getCh() + "->");
            EdgeNode e = head[i].getFirst();
            for (int j = 0; j < n; j++) {
                while (e != null) {
                    System.out.print(head[e.getData()].getCh() + ",");
                    e = e.getNext();
                }
            }
            System.out.println();
        }
    }
    public void DFS(int i){
        boolean b[] = new boolean[n];
        Stack s = new Stack();
        s.push(i);
        b[i] = true;
        while(!s.isEmpty()){
            i = s.pop();
            System.out.print(head[i].getCh()+" ");
            EdgeNode e = head[i].getFirst();
            while(e!=null){
                if(b[e.getData()]==false){
                    s.push(e.getData());
                    b[e.getData()] = true;
                }
                e = e.getNext();
            }
        }
    }
}

// 头结点
class HeadNode {
    private char ch;
    private EdgeNode first;

    public HeadNode() {

    }

    public HeadNode(char ch) {
        this.ch = ch;
        first = null;
    }

    public char getCh() {
        return ch;
    }

    public void setCh(char ch) {
        this.ch = ch;
    }

    public EdgeNode getFirst() {
        return first;
    }

    public void setFirst(EdgeNode first) {
        this.first = first;
    }
}

// 边结点
class EdgeNode {
    private int data;
    private int weight;
    private EdgeNode next;

    public EdgeNode() {
    }

    public EdgeNode(int data, int weight) {
        this.data = data;
        this.weight = weight;
        next = null;
    }

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public int getWeight() {
        return weight;
    }

    public void setWeight(int weight) {
        this.weight = weight;
    }

    public EdgeNode getNext() {
        return next;
    }

    public void setNext(EdgeNode next) {
        this.next = next;
    }
}

class Stack {
    private int top;
    private int data[];
    

    public Stack() {
        data = new int[100];
        top = 0;
    }

    public void push(int e) {
        data[top++] = e;
    }

    public int pop() {
        return data[--top];
    }

    public boolean isEmpty() {
        if (top == 0)
            return true;
        return false;
    }

    public int getTop() {
        return top;
    }

    public void setTop(int top) {
        this.top = top;
    }

    public int[] getData() {
        return data;
    }

    public void setData(int[] data) {
        this.data = data;
    }
    
}
View Code

 

posted @ 2018-04-05 10:21  leonard丶zou  阅读(142)  评论(0)    收藏  举报