数据结构 实验三、图的基本操作

1、分别定义图的邻接矩阵和邻接表存储结构;

2、分别在两种存储结构下根据输入的顶点和边(或弧)创建图;

3、分别在两种存储结构下实现求顶点度的操作;

4、分别在两种存储结构下实现图的深度和广度优先遍历算法;

5、实现图的邻接矩阵和邻接表存储结构的转换。

IGraph.java
package experiment3;

public interface IGraph {
    void createGraph();
    int getVexNum();
    int getArcNum();
    Object getVex(int v)throws Exception;
    int locateVex(Object vex);
    int firstAdjVex(int v)throws Exception;
    int nextAdjVex(int v,int w)throws Exception;
}
ALGraph.java
package experiment3;

import java.util.Scanner;

import static experiment3.GraphKind.DG;

//邻接表
public class ALGraph implements IGraph {
    private GraphKind kind;
    private int vexNum,arcNum;
    private VNode[]vexs;
    public ALGraph(){
        this(null,0,0,null);
    }
    public ALGraph(GraphKind kind, int vexNum, int arcNum, VNode[]vexs){
        this.kind=kind;
        this.vexNum=vexNum;
        this.arcNum=arcNum;
        this.vexs=vexs;
    }
    public void createGraph(){
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入图的类型:");
        GraphKind kind=GraphKind.valueOf(scanner.next());
        switch (kind){
            case DG:
                createDG();
                break;
            case UDG:
                createUDG();
                break;
        }
    }
    public void createDG(){
        Scanner scanner=new Scanner(System.in);
        System.out.println("请分别输入图的顶点数、图的边数:");
        vexNum=scanner.nextInt();
        arcNum=scanner.nextInt();
        vexs=new VNode[vexNum];
        System.out.println("请分别输入图的各顶点:");
        for (int v=0;v<vexNum;v++)
            vexs[v]=new VNode(scanner.next());
        System.out.println("请输入各边的两个顶点:");
        for (int k=0;k<arcNum;k++){
            int v=locateVex(scanner.next());
            int u=locateVex(scanner.next());
            addArc(v,u,1);
        }
    }
    public void createUDG(){
        Scanner scanner=new Scanner(System.in);
        System.out.println("请分别输入图的顶点数、图的边数:");
        vexNum=scanner.nextInt();
        arcNum=scanner.nextInt();
        vexs=new VNode[vexNum];
        System.out.println("请分别输入图的各顶点:");
        for (int v=0;v<vexNum;v++)
            vexs[v]=new VNode(scanner.next());
        System.out.println("请输入各边的两个顶点:");
        for (int k=0;k<arcNum;k++){
            int v=locateVex(scanner.next());
            int u=locateVex(scanner.next());
            addArc(v,u,1);
            addArc(u,v,1);
        }
    }
    public void addArc(int v,int u,int value){
        ArcNode arc=new ArcNode(u,value);
        arc.nextArc=vexs[v].firstArc;
        vexs[v].firstArc=arc;
    }

    @Override
    public int getArcNum() {
        return arcNum;
    }

    @Override
    public int getVexNum() {
        return vexNum;
    }
    public int locateVex(Object vex) {
        for (int v=0;v<vexNum;v++) {
            if (vexs[v].data.equals(vex))
                return v;
        }
        return -1;
    }

    public VNode[] getVexs() {
        return vexs;
    }

    public GraphKind getKind() {
        return kind;
    }

    @Override
    public Object getVex(int v) throws Exception {
        if (v<0||v>=vexNum)
            throw new Exception("第"+v+"个顶点不存在");
        return vexs[v].getData();
    }

    @Override
    public int firstAdjVex(int v) throws Exception {
        if (v<0||v>=vexNum)
            throw new Exception("第"+v+"个顶点不存在");
        VNode vex=vexs[v];
        if(vex.firstArc!=null)
            return vex.firstArc.adjVex;
        else return -1;
    }

    @Override
    public int nextAdjVex(int v, int w) throws Exception {
        if (v<0||v>=vexNum)
            throw new Exception("第"+v+"个顶点不存在");
        VNode vex=vexs[v];
        ArcNode arcNode=null;
        for (ArcNode arcNode1=vex.firstArc;arcNode1!=null;arcNode1=arcNode1.nextArc)
            if (arcNode1.adjVex==w){
                arcNode=arcNode1;
                break;
            }
        if (arcNode!=null&&arcNode.nextArc!=null)
            return arcNode.nextArc.adjVex;
        else return -1;
    }
    public  int[]findInDegree(ALGraph G)throws Exception{
        int[]indegree=new int[G.getVexNum()];
        for (int i=0;i<G.getVexNum();i++)
            for (ArcNode arcNode=G.getVexs()[i].firstArc;arcNode!=null;arcNode=arcNode.nextArc)
                ++indegree[arcNode.adjVex];
            return indegree;
    }
    public  int[]findOutDegree(ALGraph G)throws Exception{
        int []outdegree=new int[G.getVexNum()];
        for (int i=0;i<G.getVexNum();i++)
            for (ArcNode arcNode=G.getVexs()[i].firstArc;arcNode!=null;arcNode=arcNode.nextArc)
                ++outdegree[i];
            return outdegree;
    }
    public void Degree(ALGraph G)throws Exception{
        int []indegree=G.findInDegree(G);
        int []outdegree=G.findOutDegree(G);
        int []degree=new int[G.getVexNum()];
        for (int i=0;i<G.getVexNum();i++) {
            degree[i] = indegree[i] + outdegree[i];
            System.out.println("第"+i+"号顶点的度"+degree[i]);
        }

    }
    public MGraph exchange(ALGraph G)throws Exception{
        Object vexs[]=new Object[G.getVexNum()];
        int arcs[][]=new int[G.getVexNum()][G.getVexNum()];
        for (int i=0;i<G.getVexNum();i++){
            vexs[i]=G.getVex(i);
        }
        for (int i=0;i<G.getVexNum();i++)
            for (int j=0;j<G.getVexNum();j++)
                arcs[i][j]=0;
            for (int i=0;i<G.getVexNum();i++){
                ArcNode arcNode=G.vexs[i].firstArc;
                while (arcNode!=null){
                    arcs[i][arcNode.adjVex]=1;
                    arcNode=arcNode.nextArc;
                }
            }
        MGraph mGraph=new MGraph(DG,G.getVexNum(),G.getArcNum(),vexs,arcs);
        return mGraph;
    }
    public void printlist(ALGraph G){
        for (int i=0;i<G.getVexNum();i++) {
            System.out.print(vexs[i].data);
            ArcNode p=vexs[i].firstArc;
            while (p!=null) {
                int m=p.adjVex+1;
                System.out.print("v"+m);
                p=p.nextArc;
            }
            System.out.println();
        }
    }
}
ArcNode.java
package experiment3;
//图的邻接表存储表示中的边结点类
public class ArcNode {
    public int adjVex;//该弧所指向的顶点的位置
    public int value;//边的权值
    public ArcNode nextArc;//指向的下一条弧;
    public ArcNode() {
        this(-1,0,null);
    }
    public ArcNode(int adjVex){

        this(adjVex,0,null);
    }
    public ArcNode(int adjVex,int value){
        this(adjVex,value,null);
    }
    public ArcNode(int adjVex,int value,ArcNode nextArc){
        this.adjVex=adjVex;
        this.value=value;
        this.nextArc=nextArc;
    }
}
BFSTraverse.java
package experiment3;

import homework.LinkQueue;
//广度优先遍历
public class BFSTraverse {
    private static boolean[]visited;
    public static void BFSTraverse(IGraph G)throws Exception{
        visited=new boolean[G.getVexNum()];
        for (int v=0;v<G.getVexNum();v++)
            visited[v]=false;
        for (int v=0;v<G.getVexNum();v++)
            if (!visited[v])
                BFS(G,v);
    }
    private static void BFS(IGraph G,int v)throws Exception{
        visited[v]=true;
        System.out.print(G.getVex(v).toString()+" ");
        LinkQueue Q=new LinkQueue();
        Q.offer(v);
        while (!Q.isEmpty()){
            int u=(Integer)Q.poll();
            for (int w=G.firstAdjVex(u);w>=0;w=G.nextAdjVex(u,w))
                if (!visited[w]){
                    visited[w]=true;
                    System.out.print(G.getVex(w).toString()+" ");
                    Q.offer(w);
                }
        }
    }
}
DTraverser.java
package experiment3;
//深度优先遍历
public class DTraverser {
    private static boolean[]visited;
    public static void DFSTraverse(IGraph G)throws Exception{
        visited=new boolean[G.getVexNum()];
        for (int v=0;v<G.getVexNum();v++)
            visited[v]=false;
        for (int v=0;v<G.getVexNum();v++)
            if (!visited[v])
                DFS(G,v);
    }
    public static void DFS(IGraph G,int v)throws Exception{
        visited[v]=true;
        System.out.print(G.getVex(v).toString()+" ");
        for (int w=G.firstAdjVex(v);w>=0;w=G.nextAdjVex(v,w))
            if (!visited[w])
                DFS(G,w);
    }
}
GraphKind.java
package experiment3;

public enum GraphKind {
    UDG,
    DG,
}
MGraph.java
package experiment3;

import java.util.Scanner;
import java.util.Stack;

//邻接矩阵
public class MGraph implements IGraph{
    public final static int start=0;
    private GraphKind kind;
    private int vexNum,arcNum;
    private Object[]vexs;
    private int[][]arcs;
    private static boolean[]visited;
    public MGraph(){
        this(null,0,0,null,null);
    }
    public MGraph(GraphKind kind,int vexNum,int arcNum,Object[]vexs,int[][]arcs){
        this.kind=kind;
        this.vexNum=vexNum;
        this.arcNum=arcNum;
        this.vexs=vexs;
        this.arcs=arcs;
    }

    @Override
    public void createGraph() {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入图的类型:");
        GraphKind kind = GraphKind.valueOf(sc.next());
        switch (kind) {
            case UDG:
                createUDG();
                return;
            case DG:
                createDG();
                return;
        }
    }
    public void  createUDG(){
        Scanner scanner=new Scanner(System.in);
        System.out.println("请分别输入图的顶点数、图的边数:");
        vexNum=scanner.nextInt();
        arcNum=scanner.nextInt();
        vexs=new Object[vexNum];
        System.out.println("请分别输入图的各个顶点:");
        for (int v=0;v<vexNum;v++)
            vexs[v]=scanner.next();
        arcs=new int[vexNum][vexNum];
        for (int v=0;v<vexNum;v++)
            for (int u=0;u<vexNum;u++)
                arcs[v][u]=start;
            System.out.println("请输入各个边的两个顶点:");
            for (int k=0;k<arcNum;k++){
                int v=locateVex(scanner.next());
                int u=locateVex(scanner.next());
                arcs[v][u]=arcs[u][v]=1;
            }
    }
    public void createDG(){
        Scanner scanner=new Scanner(System.in);
        System.out.println("请分别输入图的顶点数、图的边数:");
        vexNum=scanner.nextInt();
        arcNum=scanner.nextInt();
        vexs=new Object[vexNum];
        System.out.println("请分别输入图的各个顶点:");
        for (int v=0;v<vexNum;v++)
            vexs[v]=scanner.next();
        arcs=new int[vexNum][vexNum];
        for (int v=0;v<vexNum;v++)
            for (int u=0;u<vexNum;u++)
                arcs[v][u]=start;
        System.out.println("请输入各个边的两个顶点:");
        for (int k=0;k<arcNum;k++){
            int v=locateVex(scanner.next());
            int u=locateVex(scanner.next());
            arcs[v][u]=1;
        }
    }
    //返回顶点数
    @Override
    public int getVexNum() {
        return vexNum;
    }
    //返回边数
    @Override
    public int getArcNum() {
        return arcNum;
    }
    //定位顶点vex在图中的位置
    @Override
    public int locateVex(Object vex) {
        for (int v=0;v<vexNum;v++)
            if (vexs[v].equals(vex))
                return v;
            return -1;
    }
    //返回v表示结点的值
    public Object getVex(int v)throws Exception{
        if (v<0||v>=vexNum)
            throw new Exception("第"+v+"个顶点不存在");
        return vexs[v];
    }

    @Override
    public int firstAdjVex(int v) throws Exception{
        if (v<0||v>=vexNum)
            throw new Exception("第"+v+"个顶点不存在");
        for (int j=0;j<vexNum;j++)
            if (arcs[v][j]==1)
                return j;
        return -1;
    }

    @Override
    public int nextAdjVex(int v, int w) throws Exception {
        if (v<0||v>=vexNum)
            throw new Exception("第"+v+"个顶点不存在");
        for (int j=w+1;j<vexNum;j++)
            if (arcs[v][j]==1)
                return j;
        return -1;
    }

    public GraphKind getKind() {
        return kind;
    }

    public int[][] getArcs() {
        return arcs;
    }

    public Object[] getVexs() {
        return vexs;
    }
    //作业
    public void DirectedGraph(IGraph G) throws Exception{
        //初始化节点遍历的数组
        visited=new boolean[G.getVexNum()];
        for (int i = 0; i <G.getVexNum(); i++) {
            visited[i] = false;
        }
        //定义存储遍历节点的栈
        Stack<Integer> s = new Stack();
        for (int i = 0; i < G.getVexNum(); i++) {
            if (!visited[i]) {
        //未访问的节点入栈
                s.add(i);
                visited[i] = true;
                while (!s.isEmpty()) {
                    //出栈
                    int j = s.pop();
                    System.out.print(G.getVex(j).toString() + " ");
                    for (int k = G.firstAdjVex(j); k >= 0; k = G.nextAdjVex(j, k)) {
                        if (!visited[k])
                            s.add(k);
                        visited[k] = true;
                    }
                }
            }
        }
    }
    public  int[]findInDegree(MGraph G)throws Exception{
        int[]indegree=new int[G.getVexNum()];
        for (int i=0;i<G.getVexNum();i++)
            for (int j=0;j<G.getVexNum();j++)
                if (arcs[j][i]!=0)
                    indegree[i]++;
                return indegree;
    }
    public  int[]findOutDegree(MGraph G)throws Exception{
        int []outdegree=new int[G.getVexNum()];
        for (int i=0;i<G.getVexNum();i++)
            for (int j=0;j<G.getVexNum();j++)
                if (arcs[i][j]!=0)
                    outdegree[i]++;
                return outdegree;
    }
    public void Degree(MGraph G)throws Exception{
        int[]indegree=G.findInDegree(G);
        int[]outdegree=G.findOutDegree(G);
        int[]degree=new int[G.getVexNum()];
        for (int i=0;i<G.getVexNum();i++){
            degree[i]=indegree[i]+outdegree[i];
            System.out.println("第"+i+"号顶点的度"+degree[i]);
        }
    }
    public ALGraph exchange(MGraph G)throws Exception{
        VNode[]Vexs=new VNode[G.vexNum];
        for (int m=0;m<G.vexNum;m++) {
            Vexs[m]=new VNode(G.vexs[m]);
            for (int n = 0; n < G.vexNum; n++) {
                if (arcs[m][n] == 1){
                    ArcNode arcNode=new ArcNode(n);
                    G.Head(arcNode,Vexs[m]);
                }
            }
        }
        ALGraph alGraph=new ALGraph(GraphKind.DG,G.vexNum,G.arcNum,Vexs);
        return alGraph;
    }
    public void Head(ArcNode n,VNode vNode){
        ArcNode p;
        p=vNode.firstArc;
        vNode.firstArc = n;
        n.nextArc = p;
    }
    public void printlist(MGraph G){
        for (int i=0;i<G.vexNum;i++) {
            for (int j = 0; j < G.vexNum; j++) {
                    System.out.print(arcs[i][j] + " ");
            }
            System.out.println();
        }
    }
}
VNode.java
package experiment3;
//图的邻接表存储表示中的顶点结点类
public class VNode {
    public Object data;//顶点信息
    public ArcNode firstArc;//指向第一条依附于该顶点的弧
    public VNode(Object data){
        this(data,null);
    }
    public VNode(Object data,ArcNode firstArc){
        this.data=data;
        this.firstArc=firstArc;
    }

    public Object getData() {
        return data;
    }

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

    public ArcNode getFirstArc() {
        return firstArc;
    }

    public void setFirstArc(ArcNode firstArc) {
        this.firstArc = firstArc;
    }
}
TestALGraph.java
package experiment3;

import java.util.Scanner;

public class TestALGraph {
    //邻接表测试
        public static void main(String[] args) throws Exception{
            /*ArcNode v12=new ArcNode(1);
            VNode v1=new VNode("v1",v12);
            ArcNode v23=new ArcNode(2);
            ArcNode v24=new ArcNode(3,0,v23);
            VNode v2=new VNode("v2",v24);
            ArcNode v34=new ArcNode(3);
            VNode v3=new VNode("v3",v34);
            VNode v4=new VNode("v4");
            VNode []vexs={v1,v2,v3,v4};
            ALGraph alGraph=new ALGraph(GraphKind.DG,4,4,vexs);
            alGraph.Degree(alGraph);
            DTraverser dTraverser=new DTraverser();
            System.out.print("邻接表的深度优先遍历:");
            dTraverser.DFSTraverse(alGraph);
            BFSTraverse bfsTraverse=new BFSTraverse();
            System.out.print("邻接表的广度优先遍历:");
            bfsTraverse.BFSTraverse(alGraph);
            System.out.println();
            alGraph.printlist(alGraph);
            MGraph mGraph=alGraph.exchange(alGraph);
            System.out.println();
            mGraph.Degree(mGraph);
            System.out.print("转化成邻接矩阵的深度优先遍历:");
            dTraverser.DFSTraverse(mGraph);
            System.out.print("转化成邻接矩阵的广度优先遍历:");
            bfsTraverse.BFSTraverse(mGraph);
            System.out.println();
            mGraph.printlist(mGraph);*/
            ALGraph alGraph=new ALGraph();
            Scanner scanner=new Scanner(System.in);
            alGraph.createDG();
            /*System.out.println("请输入v:(0<=v):");
            int v1=scanner.nextInt();
            System.out.println("v"+(v1+1)+"的第一个邻接点:"+"v"+(alGraph.firstAdjVex(v1)+1));
            System.out.println("请输入v和w,中间以空格分开(0<=v,w<vexNum):");
            int v2=scanner.nextInt();
            int w=scanner.nextInt();
            int a=alGraph.nextAdjVex(v2,w);
            //v2+1,w+1,a+1为的是和v1,v2,v3,v4相对应。
            if (a==-1){
                System.out.println("v"+(v2+1)+"相对于"+"v"+(w+1)+"没有下一个邻接点");
            }else {
                System.out.println("v" + (v2 + 1) + "相对于" + "v" + (w+1) + "的下一个邻接点" + "v" + (a+1));
            }
            alGraph.Degree(alGraph);*/
            DTraverser dTraverser=new DTraverser();
            System.out.print("邻接表的深度优先遍历:");
            dTraverser.DFSTraverse(alGraph);
            BFSTraverse bfsTraverse=new BFSTraverse();
            System.out.print("邻接表的广度优先遍历:");
            bfsTraverse.BFSTraverse(alGraph);
            System.out.println();
            /*alGraph.printlist(alGraph);
            MGraph mGraph=alGraph.exchange(alGraph);
            System.out.println();
            mGraph.Degree(mGraph);
            System.out.print("转化成邻接矩阵的深度优先遍历:");
            dTraverser.DFSTraverse(mGraph);
            System.out.print("转化成邻接矩阵的广度优先遍历:");
            bfsTraverse.BFSTraverse(mGraph);
            System.out.println();
            mGraph.printlist(mGraph);*/
        }
    }
TestMGraph.java
package experiment3;

import java.util.Scanner;

public class TestMGraph {
    //邻接矩阵测试
        public static void main(String[] args) throws Exception{
            /*Object vexs[]={"v1","v2","v3","v4"};
            int [][]arcs={{0,1,0,0},{0,0,1,1},{0,0,0,1},{0,0,0,0}};
            MGraph mGraph=new MGraph(GraphKind.DG,4,4,vexs,arcs);
            mGraph.Degree(mGraph);
            DTraverser dTraverser=new DTraverser();
            System.out.print("邻接表的深度优先遍历:");
            dTraverser.DFSTraverse(mGraph);
            BFSTraverse bfsTraverse=new BFSTraverse();
            System.out.print("邻接表的广度优先遍历:");
            bfsTraverse.BFSTraverse(mGraph);
            System.out.println();
            mGraph.printlist(mGraph);
            ALGraph alGraph=mGraph.exchange(mGraph);
            System.out.println();
            alGraph.Degree(alGraph);
            System.out.print("转化成邻接矩阵的深度优先遍历:");
            dTraverser.DFSTraverse(alGraph);
            System.out.print("转化成邻接矩阵的广度优先遍历:");
            bfsTraverse.BFSTraverse(alGraph);
            System.out.println();
            alGraph.printlist(alGraph);*/
            MGraph mGraph=new MGraph();
            Scanner scanner=new Scanner(System.in);
            mGraph.createDG();
            System.out.println("请输入v:(0<=v):");
            int v1=scanner.nextInt();
            System.out.println("v"+(v1+1)+"的第一个邻接点:"+"v"+(mGraph.firstAdjVex(v1)+1));
            System.out.println("请输入v和w,中间以空格分开(0<=v,w<vexNum):");
            int v2=scanner.nextInt();
            int w=scanner.nextInt();
            int a=mGraph.nextAdjVex(v2,w);
            //v2+1,w+1,a+1为的是和v1,v2,v3,v4相对应。
            if (a==-1){
                System.out.println("v"+(v2+1)+"相对于"+"v"+(w+1)+"没有下一个邻接点");
            }else {
                System.out.println("v" + (v2 + 1) + "相对于" + "v" + (w+1) + "的下一个邻接点" + "v" + (a+1));
            }
            mGraph.Degree(mGraph);
            DTraverser dTraverser=new DTraverser();
            System.out.print("邻接表的深度优先遍历:");
            dTraverser.DFSTraverse(mGraph);
            BFSTraverse bfsTraverse=new BFSTraverse();
            System.out.print("邻接表的广度优先遍历:");
            bfsTraverse.BFSTraverse(mGraph);
            System.out.println();
            mGraph.printlist(mGraph);
            ALGraph alGraph=mGraph.exchange(mGraph);
            System.out.println();
            alGraph.Degree(alGraph);
            System.out.print("转化成邻接矩阵的深度优先遍历:");
            dTraverser.DFSTraverse(alGraph);
            System.out.print("转化成邻接矩阵的广度优先遍历:");
            bfsTraverse.BFSTraverse(alGraph);
            System.out.println();
            alGraph.printlist(alGraph);
        }
    }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@8055@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值