java-广度优先搜索+深度优先搜索+拓扑排序

StackX.java

package demo;

public class StackX {
    private final int SIZE = 20;
    private int[] st;
    private int top;

    public StackX(){
        st = new int[SIZE];
        top = -1;
    }

    public void push(int j){
        st[++top] = j;
    }

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

    public int peek(){
        return st[top];
    }

    public boolean isEmpty(){
        return (top==-1);
    }
}

QueueX.java

package demo;

public class QueueX {
    private final int SIZE = 20;
    private int[] queArray;
    private int front;
    private int rear;

    public QueueX(){
        queArray = new int[SIZE];
        front = 0;
        rear = -1;
    }

    public void insert(int j){
        if (rear == SIZE-1)
            rear = -1;
        queArray[++rear] = j;
    }

    public int remove(){
        int temp = queArray[front++];
        if (front == SIZE){
            front = 0;
        }
        return temp;
    }

    public boolean isEmpty(){
        return (rear+1 == front || front+SIZE-1 == rear);
    }

}

DirectedGraph.java

package demo;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

public class DirectedGraph {
	private class Vertex{
        private String vertexLabel;// 顶点标识
        private List<Edge> adjEdges;
        private int inDegree;// 该顶点的入度

        public Vertex(String verTtexLabel) {
            this.vertexLabel = verTtexLabel;
            inDegree = 0;
            adjEdges = new LinkedList<Edge>();
        }
    }

    private class Edge {
        private Vertex endVertex;

        // private double weight;
        public Edge(Vertex endVertex) {
            this.endVertex = endVertex;
        }
    }

    private Map<String, Vertex> directedGraph;

    public DirectedGraph(String[] graphContent) {
        directedGraph = new LinkedHashMap<String, DirectedGraph.Vertex>();
        buildGraph(graphContent);
    }

    private void buildGraph(String[] lines) {
        Vertex startNode, endNode;
        String startNodeLabel, endNodeLabel;
        Edge e;
        for (int i = 0; i < lines.length; i++) {
            String[] nodesInfo = lines[i].split(",");
            startNodeLabel = nodesInfo[0];
            endNodeLabel = nodesInfo[1];
            startNode = directedGraph.get(startNodeLabel);
            if(startNode == null){
                startNode = new Vertex(startNodeLabel);
                directedGraph.put(startNodeLabel, startNode);
            }
            endNode = directedGraph.get(endNodeLabel);
            if(endNode == null){
                endNode = new Vertex(endNodeLabel);
                directedGraph.put(endNodeLabel, endNode);
            }

            e = new Edge(endNode);//每读入一行代表一条边
            startNode.adjEdges.add(e);//每读入一行数据,起始顶点添加一条边
            endNode.inDegree++;//每读入一行数据,终止顶点入度加1
        }
    }

    public void topoSort() throws Exception{
        int count = 0;

        Queue<Vertex> queue = new LinkedList<>();// 拓扑排序中用到的栈,也可用队列.
        //扫描所有的顶点,将入度为0的顶点入队列
        Collection<Vertex> vertexs = directedGraph.values();
        for (Vertex vertex : vertexs)
            if(vertex.inDegree == 0)
                queue.offer(vertex);

        while(!queue.isEmpty()){
            Vertex v = queue.poll();
            System.out.print(v.vertexLabel + " ");
            count++;
            for (Edge e : v.adjEdges)
                if(--e.endVertex.inDegree == 0)
                    queue.offer(e.endVertex);
        }
        if(count != directedGraph.size())
            throw new Exception("Graph has circle");
    }
}

main

package demo;

public class Gra {
    private final int MAX_VERTS = 20;//表示顶点的个数
    private Vertex vertexList[];//用来存储顶点的数组
    private int adjMat[][];//用邻接矩阵来存储边,数组元素表示没有边界,1表示有边界
    private int nVerts;//顶点个数
    private StackX theStack;//用栈实现深度优先搜索
    private QueueX queue;//用队列实现广度优先搜索

    /**
     * 顶点类
     * */
    class Vertex{
        public char label;
        public boolean wasVisited;
        public Vertex(char label){
            this.label = label;
            wasVisited = false;
        }
    }

    public Gra(){
        vertexList = new Vertex[MAX_VERTS];
        adjMat = new int[MAX_VERTS][MAX_VERTS];
        nVerts = 0;//初始化顶点个数为0
        //初始化邻接矩阵所有元素都为0,即所有顶点都没有边
        for (int i=0;i<MAX_VERTS;i++){
            for (int j=0;j<MAX_VERTS;j++){
                adjMat[i][j] = 0;
            }
        }
        theStack = new StackX();
        queue = new QueueX();
    }

    //将顶点添加到数组中,是否访问标志置为wasVisited=false(未访问)、
    public void addVertex(char lab){
        vertexList[nVerts++] = new Vertex(lab);
    }

    //注意用邻接矩阵表示边,是对称的,两部分都要赋值
    public void addEdge(int start,int end,int weight){
    	int idx1 = start - 65;
		int idx2 = end - 65;
        adjMat[idx1][idx2] = 1;
        adjMat[idx2][idx1] = 1;
    }

    //打印某个顶点表示的值
    public void displayVertex(int v){
        System.out.print(vertexList[v].label+" ");
    }

    /**深度优先搜索算法
     * 1、用peek方法检查栈顶的顶点
     * 2、用getAdjUnvisitedVertex方法找到当前栈顶邻接且未被访问的顶点
     * 3、第二步返回值不等于-1则找到下一个未访问的邻接顶点,访问这个顶点,并入栈
     *    如第二步返回值等于-1,则没有找到,出栈
     * */
    public void depthFirstSearch(){
        //从第一个顶点开始访问
        vertexList[0].wasVisited = true;//访问之后标记为true
        displayVertex(0);
        theStack.push(0);

        while (!theStack.isEmpty()){
            //找到栈当前顶点邻接且未被访问的顶点
            int v = getAdjUnvisitedVertex(theStack.peek());
            if (v==-1){//如果当前顶点值为-1,则表示没有邻接且未被访问的顶点,那么出栈顶点
                theStack.pop();
            }else {
                //否则访问下一个邻接点
                vertexList[v].wasVisited = true;
                displayVertex(v);
                theStack.push(v);
            }
        }

        //栈访问完毕,重置所有标记位为false
        for (int i=0;i<nVerts;i++){
            vertexList[i].wasVisited = false;
        }
    }

    //找到与某一顶点邻接且未被访问的顶点
    public int getAdjUnvisitedVertex(int v){
        for (int i=0;i<nVerts;i++){
            //v顶点与i顶点相邻且未被访问
            if (adjMat[v][i]==1&&vertexList[i].wasVisited==false)
                return i;
        }
        return -1;
    }

    /**广度优先搜索
     * 1、用remove方法检查栈顶的栈顶
     * 2、试图找到这个顶点还未被访问的邻接点
     * 3、如果没有找到,该顶点出列
     * 4、如果找到这样的顶点,访问这个顶点,并把它放入队列中
     * */
    public void breadthFirstSearch(){
        vertexList[0].wasVisited = true;
        displayVertex(0);
        queue.insert(0);
        int v2;

        while(!queue.isEmpty()){
            int v1 = queue.remove();
            while ((v2 =getAdjUnvisitedVertex(v1))!=-1){
                vertexList[v2].wasVisited = true;
                displayVertex(v2);
                queue.insert(v2);
            }
        }

        //搜索完毕,初始化,便于下次搜索
        for (int i=0;i<nVerts;i++){
            vertexList[i].wasVisited = false;
        }
    }

    public static void main(String[] args) {
        Gra graph = new Gra();
        for (int i = 0; i < 10; i++) {
			graph.addVertex((char)(65 + i));
		}
		graph.addEdge('A', 'B', 6);
		graph.addEdge('B', 'C', 3);
		graph.addEdge('A', 'I', 9);
		graph.addEdge('A', 'D', 4);
		graph.addEdge('D', 'B', 3);
		graph.addEdge('B', 'E', 1);
		graph.addEdge('D', 'E', 4);
		graph.addEdge('E', 'C', 2);
		graph.addEdge('C', 'F', 2);
		graph.addEdge('E', 'F', 8);
		graph.addEdge('D', 'G', 6);
		graph.addEdge('G', 'E', 6);
		graph.addEdge('E', 'H', 7);
		graph.addEdge('H', 'F', 11);
		graph.addEdge('I', 'G', 2);
		graph.addEdge('G', 'J', 2);
		graph.addEdge('I', 'J', 1);
		graph.addEdge('G', 'H', 3);
		graph.addEdge('J', 'H', 4);

        System.out.println("深度优先搜索算法:");
        graph.depthFirstSearch();

        System.out.println();
        System.out.println("---------------");

        System.out.println("广度优先搜索算法:");
        graph.breadthFirstSearch();
        
        System.out.println("\n===============");
        
        Gra graph2 = new Gra();
        for (int i = 0; i < 16; i++) {
			graph2.addVertex((char)(65 + i));
		}
		graph2.addEdge('A', 'B', 1);
		graph2.addEdge('B', 'C', 18);
		graph2.addEdge('C', 'D', 20);
		graph2.addEdge('A', 'E', 2);
		graph2.addEdge('E', 'F', 10);
		graph2.addEdge('B', 'F', 4);
		graph2.addEdge('F', 'G', 13);
		graph2.addEdge('C', 'G', 1);
		graph2.addEdge('G', 'H', 22);
		graph2.addEdge('D', 'H', 4);
		graph2.addEdge('E', 'I', 5);
		graph2.addEdge('I', 'J', 11);
		graph2.addEdge('J', 'F', 6);
		graph2.addEdge('J', 'K', 4);
		graph2.addEdge('K', 'G', 11);
		graph2.addEdge('K', 'L', 23);
		graph2.addEdge('H', 'L', 5);
		graph2.addEdge('I', 'M', 3);
		graph2.addEdge('M', 'N', 1);
		graph2.addEdge('J', 'N', 9);
		graph2.addEdge('N', 'O', 9);
		graph2.addEdge('O', 'K', 12);
		graph2.addEdge('O', 'P', 8);
		graph2.addEdge('P', 'L', 9);

        System.out.println("深度优先搜索算法:");
        graph2.depthFirstSearch();

        System.out.println();
        System.out.println("---------------");

        System.out.println("广度优先搜索算法:");
        graph2.breadthFirstSearch();
        
        System.out.println("\n===============");
        
        String[] graphContent = "A,B;B,C;C,F;A,D;B,D;B,E;E,C;E,F;D,E;D,G;E,G;G,F;F,H;H,G;G,I;I,J;H,J".split(";");
        DirectedGraph directedGraph = new DirectedGraph(graphContent);
        try{
        	directedGraph.topoSort();
        }catch(Exception e){
        	System.out.println("graph has circle");
        	//e.printStackTrace();
        }
        /*
         * 输出
深度优先搜索算法:
A B C E D G H F J I 
---------------
广度优先搜索算法:
A B D I C E G J F H 
===============
深度优先搜索算法:
A B C D H G F E I J K L P O N M 
---------------
广度优先搜索算法:
A B E C F I D G J M H K N L O P 
===============
A B D E C graph has circle
         
         */
        
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值