5图

1图的概念

  • 在图中最基本的单位是顶点,顶点之间的关联关系称为边
  • 有些边涉及权重,有权重的图被称为带权图
  • 其他还有有向图和无向图

2图的存储方式

​ 2.1邻接矩阵

  • 有n个顶点,创建一个n*n的矩阵,矩阵中的每一个元素都代表着从某个顶点到另一个顶点的连接状态
  • 其中1表示两顶点之间有关系,0表示两顶点之间没有关系
  • 优点:简单直观,可以快速查到一个顶点和另一个顶点之间的关联关系
  • 缺点:占用太多空间,不适合稀疏图
//邻接矩阵存储方式
public class MGraph {
    private int[][] edges;//邻接矩阵
    private int numOfEdges;//边的数目
    private int numOfVetex;//顶点的数目

    //初始化一个邻接矩阵 
    public MGraph(int n) {
        edges = new int[n][n];
        numOfEdges = 0;
        numOfVetex = n;
    }

    //初始化一个邻接矩阵并且以一个n*n的矩阵为其赋值
    public MGraph(int[][] edges,int n){
        numOfVetex=n;
        numOfEdges=0;
        this.edges = new int[n][n];
        for(int i=0;i<n;i++){
            for(int j=0;j<n;j++){
                this.edges[i][j]=edges[i][j];
                if((edges[i][j]!=-1)&&(edges[i][j]!=0)){
                    numOfEdges++;
                }
            }
        }
    }

    public static void main(String args[]){
        int[][] edges={{0,2,-1,-1},{-1,0,3,1},{-1,-1,0,4},{5,-1,-1,0}};
        MGraph m=new MGraph(edges,4);
    }
}

​ 2.2邻接表

  • 在邻接表中,图的每一个顶点都是一个链表的头节点,其后连接着该顶点能够直接到达的相邻节点
  • 逆邻接表和邻接表正好相反:逆邻接表每一个顶点作为链表的头节点,后继节点所存储的是能够直接到达该顶点的相邻顶点
public class LGraph {
    //顶点节点
    private class VNode{
        int data;              //起点的序号
        ArcNode firstArc;      //指向第一条边

        public VNode(int data, ArcNode firstArc) {
            this.data = data;
            this.firstArc = firstArc;
        }

        public int getData() {
            return data;
        }
        public void setData(int data) {
            this.data = data;
        }
        public ArcNode getFirstArc() {
            return firstArc;
        }
        public void setFirstArc(ArcNode firstArc) {
            this.firstArc = firstArc;
        }
    }
    
    //边节点
    private class ArcNode{
        int adjvex;           //该边指向终点的序号
        ArcNode nextarc;      //下一条边的指针
        int len;              //该边的长度

        public ArcNode(int adjvex, ArcNode nextarc, int len) {
            this.adjvex = adjvex;
            this.nextarc = nextarc;
            this.len = len;
        }

        public int getAdjvex() {
            return adjvex;
        }

        public void setAdjvex(int adjvex) {
            this.adjvex = adjvex;
        }

        public ArcNode getNextarc() {
            return nextarc;
        }

        public void setNextarc(ArcNode nextarc) {
            this.nextarc = nextarc;
        }

        public int getLen() {
            return len;
        }

        public void setLen(int len) {
            this.len = len;
        }
    }

    ArrayList<VNode> vNodes;
    int numOfVetex;
    int numOfEdges;

    public LGraph() {
        vNodes=new ArrayList<VNode>();
        numOfVetex=0;
        numOfEdges=0;
    }

    public LGraph(int[][] edges,int n){
        numOfVetex=n;
        numOfEdges=0;
        vNodes=new ArrayList<VNode>();
        for(int i=0;i<n;i++){
            VNode v=new VNode(i,null);
            vNodes.add(v);
        }
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
            {
                if(edges[i][j]!=0&&edges[i][j]!=-1){
                    ArcNode arc=new ArcNode(j,null,edges[i][j]);
                    VNode v=vNodes.get(i);
                    arc.setNextarc(v.getFirstArc());
                    v.setFirstArc(arc);
                    numOfEdges++;
                }
            }
    }


    //将邻接表存储的图转化为矩阵存储的图
    public MGraph toMGraph(){
        int[][] edges=new int[numOfVetex][numOfVetex];
        for(int i=0;i<vNodes.size();i++){
            edges[i][i]=0;
            ArcNode arc=vNodes.get(i).getFirstArc();
            while(arc!=null){
                edges[i][arc.getAdjvex()]=arc.getLen();
                arc=arc.getNextarc();
            }
        }
        MGraph m=new MGraph(edges,numOfVetex);
        return m;

    }

    public static void main(String args[]){
        int[][] edges={{0,2,-1,-1},{-1,0,3,1},{-1,-1,0,4},{5,-1,-1,0}};
        LGraph l=new LGraph(edges,4);
    }
}
  • 简易版
   //图的顶点
    private static class Vertex{
        int data;

        Vertex(int data){
            this.data=data;
        }
    }

    //图邻接表形式
    private static class Graph{
        private int size;//顶点数
        private Vertex[] vertexes;//顶点
        private LinkedList[] adj;//边

        Graph(int size){
            this.size=size;
            //初始化顶点和邻接表
            vertexes=new Vertex[size];
            adj=new LinkedList[size];
            //防止空指针
            for(int i=0;i<size;i++){
                vertexes[i]=new Vertex(i);
                adj[i]=new LinkedList();
            }
        }
    }

    public static void main(String[] args) {
        Graph graph=new Graph(3);
        graph.adj[0].add(1);
        graph.adj[0].add(2);
        graph.adj[1].add(2);
        graph.adj[2].add(0);  
    }

3图的遍历

  • 深度优先遍历(DFS)和广度优先遍历(BFS)
  • 邻接矩阵版
//邻接矩阵
//从某一个顶点开始对该图进行深度优先搜索
	public void DFS(int v) {
		int[] visited = new int[numOfVetex];
		for (int i = 0; i < numOfVetex; i++) {
			visited[i] = 0;
		}
		DFSREC(v, visited);
		System.out.println();
		int flag=1;
		for(int i=0;i<visited.length;i++){
			if(visited[i]==0)
			{
				flag=0;
				break;
			}
		}
		if(flag==1)
			System.out.println("已遍历完全图");
		else
			System.out.println("从该点出发无法遍历全图");
 
	}
	
	//深度优先搜索辅助函数
	private void DFSREC(int v, int visited[]) {
		visited[v] = 1;
		System.out.print(v + "-->");
		for (int i = 0; i < numOfVetex; i++) {
			if (edges[v][i] != -1 && edges[v][i] != 0 && visited[i] != 1) {
				DFSREC(i, visited);
			}
		}
	}

	//广度优先搜索
	public void BFS(int v) {
		int[] qu=new int[numOfVetex];
		int[] visited=new int[numOfVetex];
		int head=0;
		int tail=0;
		qu[tail++]=v;
		visited[v]=1;
		while(head!=tail){
			int t=qu[head++];
			System.out.print(t+"-->");
			for(int i=0;i<numOfVetex;i++){
				if(edges[t][i]!=-1&&edges[t][i]!=0&&visited[i]==0)
				{
					qu[tail++]=i;
					visited[i]=1;
				}
				
			}
		}
		
	}
  • 邻接表
//邻接表
//深度优先遍历
    public static void dfs(Graph graph,int start, boolean[] visited){
        System.out.println(graph.vertexes[start].data);
        visited[start]=true;
        for (Object index : graph.adj[start]){
            if (!visited[(int) index]){
                dfs(graph, (int) index,visited);
            }
        }
    }
    
    //广度优先遍历
    public static void bfs(Graph graph,int start,boolean[] visited,LinkedList<Integer> queue){
        queue.offer(start);
        while (!queue.isEmpty()){
            int front=queue.poll();
            if (visited[front]){
                continue;
            }
            System.out.println(graph.vertexes[front].data);
            visited[front]=true;
            for (Object index:graph.adj[front]){
                queue.offer((int)index);
            }
        }
    }
posted @ 2021-10-16 18:39  fao99  阅读(447)  评论(0)    收藏  举报