20162320刘先润大二 实验四 图及应用

实验涉及代码

AMatrixAMatrixTestCrossListCrossListTestRoadRoadTest


图的实现与应用-1

实验目的:用邻接矩阵实现无向图(边和顶点都要保存),实现在包含添加和删除结点的方法,添加和删除边的方法,size(),isEmpty(),广度优先迭代器,深度优先迭代器

实现思路:实现邻接矩阵得确定一个表示方法,对于结点于结点之间的关系得使用二元数组来实现。由于无向图的邻接矩阵是对称矩阵,且其左上角到右下角的对角线上值为零,这是其中应用的一条性质。所以根据实现步骤可以得出如下伪代码:

 确定图的顶点个数和边的个数; 
 输入顶点信息存储在一维数组vertex中;  
 初始化邻接矩阵; 
 依次输入每条边存储在邻接矩阵中;     
 输入边依附的两个顶点的序号i, j; 
 将邻接矩阵的第i行第j列的元素值置为1;   
 将邻接矩阵的第j行第i列的元素值置为1;

实验过程:

  • 1.创建二位数组,并确定顶点和边的变量,得出size()isEmpty()的方法,返回二维数组的大小和判定二维数组是否为空。
  • 2.插入和删除边和结点,关于结点是输入点的名称,插入边则是输入边相连的两点的坐标确定其位置以及相应的权值。若删除边和结点,则是把两点的坐标修改为0和0,并将其对应的数目减一则删除成功。
 public void addVertex(Object vertex) {
        vertexList.add(vertexList.size(),vertex);
    }

 public void insertEdge(int v1,int v2,int weight) {
        edges[v1][v2]=weight;
        numOfEdges++;
    }
 public void deleteEdge(int v1,int v2) {
        edges[v1][v2]=0;
        numOfEdges--;
    }
  • 3.得到下一个邻接结点的坐标,通过建立一个循环,查找到二维数组中索引维度下一个索引的位置,若越界则另一个索引维度加一得到返回值。
  public int getNextNeighbor(int v1,int v2) {
        for (int j=v2+1;j<vertexList.size();j++) {
            if (edges[v1][j]>0) {
                return j;
            }
        }
        return -1;
    }
  • 4.广度遍历方法,过程是对每一层节点依次访问,访问完一层进入下一层,而且每个节点只能访问一次。对于上面的例子来说,广度优先遍历的 结果是:A,B,C,D,E,F,G,H,I(假设每层节点从左到右访问)。首先私有函数广度遍历,创建一个队列保存结点,访问第i个结点并让其入队列.然后访问该结点,然后设置结点标记为已经被访问,然后入队列,并寻找下一个临接结点。
  private void broadFirstSearch(boolean[] isVisited, int i) {
        int a, b;
        LinkedList queue = new LinkedList();
        System.out.print(getValueByIndex(i) + "  ");
        isVisited[i] = true;
        queue.addLast(i);
        while (!queue.isEmpty()) {
            a = ((Integer) queue.removeFirst()).intValue();
            b = getFirstNeighbor(a);
            while (b != -1) {
                if (!isVisited[b]) {
                    System.out.print(getValueByIndex(b) + "  ");
                    isVisited[b] = true;
                    queue.addLast(b);
                }
                b = getNextNeighbor(a, b);
            }
        }
    }

    public void broadFirstSearch() {
        for(int i = 0; i< size(); i++) {
            if(!isVisited[i]) {
                broadFirstSearch(isVisited, i);
            }
        }
    }
  • 5.深度优先遍历,对每一个可能的分支路径深入到最底层,并且每个节点只能访问一次。首先访问该结点并将其打印,然后将其设置为已访问状态,如果访问到结点为二维数组尽头则从没有遍历的结点访问,以此循环下去。
 public void depthFirstSearch(boolean[] isVisited,int  i) {
        System.out.print(getValueByIndex(i)+"  ");
        isVisited[i]=true;
        int w=getFirstNeighbor(i);//
        while (w!=-1) {
            if (!isVisited[w]) {
                depthFirstSearch(isVisited,w);
            }
            w=getNextNeighbor(i, w);
        }
    }

    public void depthFirstSearch() {
        for(int i = 0; i< size(); i++) {
            if (!isVisited[i]) {
                depthFirstSearch(isVisited,i);
            }
        }
    }

实验测试:创建如图所示的图进行测试


图的实现与应用-2

实验目的:用十字链表实现无向图(边和顶点都要保存),实现在包含添加和删除结点的方法,添加和删除边的方法,size(),isEmpty(),广度优先迭代器,深度优先迭代器

实验思路:十字链表的结构可以看成是将有向图的邻接表和逆邻接表结合起来得到的。用链表模拟矩阵的行,然后再构造代表列的链表,将每一行中的元素节点插入到对应的列中去。

实验过程:

  • 1.首先定义边和结点的类,提供一个输入方法,关于结点要设置先入先出,边则需要添加同入弧和同出弧变量,以方便指向。最后入结点和出结点指向对应的边,所以边链表需要有四个区域。
 public static class Vertex<E,T>  {
        E data;
        Edge<T> firstIn;
        Edge<T> firstOut;

        public Vertex(E data) {
            this.data = data;
        }
    }

    public static class Edge<E> {
        E data;
        int From;
        int To;
        Edge<E> SameFromVertex;
        Edge<E> SameToVertex;

 public Edge(E data, int From, int To) {
            this.data = data;
            this.From = From;
            this.To = To;
        }
    }
  • 2.添加、删除边和点,首先创建两个收集集合与边的变量,用来统计二者的总数。添加点直接使用链表的添加方法并让结点总数加一即可,而删除点则需要不仅仅删除结点,还需要删除与此个结点相关的所有边的指向。添加边是需要将入结点插入到顶点或者插入到边的同入弧,如果该顶点没有入弧,则将结点指向为Null,最后添加边的总数。删除边则直接使用链表的remove方法即可。
  public void removeV(Vertex<Integer, Integer> vex){
        for (int index = 0; index< AllEdge.size(); index++){
            if (AllEdge.get(index).From== AllVertex.indexOf(vex)|| AllEdge.get(index).To== AllVertex.indexOf(vex)){
                AllEdge.remove(index);
                index=0;
            }
        }
        AllVertex.remove(vex);
    }

 public void addE(Edge<Integer> edge) {
        Edge<Integer> edge1 = new Edge<>(edge.data,edge.From,edge.To);
        Edge<Integer> edge2 = new Edge<>(edge.data,edge.From,edge.To);
        AllEdge.add(edge);
        int fromVertexIndex = edge.From;
        int toVertexIndex = edge.To;
        Vertex<Integer, Integer> fromVertex = AllVertex.get(fromVertexIndex);
        Vertex<Integer, Integer> toVertex = AllVertex.get(toVertexIndex);
        if (fromVertex.firstOut == null) {
            fromVertex.firstOut = edge1;
        } else {
            Edge<Integer> tempEdge = fromVertex.firstOut;
            while (tempEdge.SameFromVertex != null) {
                tempEdge = tempEdge.SameFromVertex;
                System.out.println();
            }
            tempEdge.SameFromVertex = edge1;
        }
        if (toVertex.firstIn == null) {
            toVertex.firstIn = edge2;
        } else {
            Edge<Integer> tempEdge = toVertex.firstIn;
            while (tempEdge.SameToVertex != null) {
                tempEdge = tempEdge.SameToVertex;
            }
            tempEdge.SameToVertex = edge2;
        }
        System.out.println();
    }
  • 3.添加size()方法需要将添加的结点保存至一个集合,否则无法得到返回值。
 static List<Vertex<Integer,Integer>> AllVertex = new ArrayList<>();
public int size(){
        return AllVertex.size();
    }
  • 4.广度以及深度遍历,深度遍历实现方法:首先选择一个顶点入栈,如果栈非空栈,则出栈并访问出栈元素,并标示为已访问。然后将出栈顶点的邻接顶点(要求未被访问过)全部入栈。重复前一步骤直至没有可以访问到的顶点。广度遍历方法:首先选择一个未被访问的顶点入队。如果队列非空队列,则出队并访问,然后标记为已被访问。并将出队顶点的邻接顶点都入队。然后重复前一个步骤直至没有可以访问的顶点。(详细代码见代码连接)

实验测试:创建一个测试图进行测试,如图所示


图的实现与应用-3

实验目的:创建计算机网络路由系统,输入网络中点到点的线路,以及每条线路使用的费用,系统输出网络中各点之间最便宜的路径,指出不相通的所有位置。

实验思路:该实验需要求出最短路径,可以通过求单源最短路径,使用Dijkstra算法。

实验过程:

  • 1.创建无向图的变量表示,存储所有顶点的一维数组,存储图中顶点与边关系的二维数组,对数组进行初始化,顶点间没有边关联的值为int类型最大值
    public Road(boolean graphType, boolean method, int size) {
        this.graphType = graphType;
        this.method = method;
        this.NumVertex = 0;
        this.matrix = size;

        if (this.method) {
            visited = new boolean[matrix];
            vertexesArr = new Object[matrix];
            edgesMatrix = new int[matrix][matrix];

            for (int row = 0; row < edgesMatrix.length; row++) {
                for (int column = 0; column < edgesMatrix.length; column++) {
                    edgesMatrix[row][column] = MAX_VALUE;
                    System.out.print("");
                }
            }
        }
    }
  • 2.求单个点到其他点的最便宜路径长度,即求最小权值路径。可以一开始假设直达路径为最短路径,在这种情况下的最后经由点就是出发点。初始数组时起点v0访问集合,表示v0 到v0的最短路径已经找到

    。然后下来假设经由一个点中转到达其余各点,会权值更小近些并验证之,然后重复该过程,直到列举完所有可能的点。创建一个循环将最短路径的权值记录并且打印出来。

public void Dijkstra(int v0) {
        int[] dist = new int[matrix];
        int[] prev = new int[matrix];

        for (int i = 0; i < NumVertex; i++) {
            dist[i] = edgesMatrix[v0][i];
            visited[i] = false;
            if (i != v0 && dist[i] < MAX_VALUE)
                prev[i] = v0;
            else
                prev[i] = -1;
        }

        visited[v0] = true;
        int minDist;
        int v = 0;
        for (int i = 1; i < NumVertex; i++) {
            minDist = MAX_VALUE;

            for (int j = 0; j < NumVertex; j++) {
                if ((!visited[j]) && dist[j] < minDist) {
                    v = j;
                    minDist = dist[j];
                }
            }
            visited[v] = true;

            for (int j = 0; j < NumVertex; j++) {
                if ((!visited[j]) && edgesMatrix[v][j] < MAX_VALUE) {
                    if (minDist + edgesMatrix[v][j] <= dist[j]) {
                        dist[j] = minDist + edgesMatrix[v][j];
                        prev[j] = v;
                    }

                }
            }

        }

        for (int i = 0; i < matrix; i++) {
            if (dist[i] > 1000) {
                dist[i] = 0;
            }
            System.out.println(vertexesArr[v0] + "到" + vertexesArr[i] + "的最短路径是:" + dist[i]);
        }
    }
  • 3.求出最短的路径可以使用Dijkstra算法。创建一个队列,通过步骤2求出最便宜权值的路径方法记录其经过并且标记的结点,将其输出出去,并且访问未标记的结点得到Dijkstra算法的最短路径。
 public void DRoad(int v0) {
        Queue<Integer> queue = new LinkedList<Integer>();
        for (int i = 0; i < NumVertex; i++) {
            visited[i] = false;
        }

        for (int i = 0; i < NumVertex; i++) {
            if (!visited[i]) {
                queue.add(i);
                visited[i] = true;
                while (!queue.isEmpty()) {
                    int row = queue.remove();
                    System.out.print(vertexesArr[row] + "→");
                    for (int k = getMin(row); k >= 0; k = getMin(row)) {
                        if (!visited[k]) {
                            queue.add(k);
                            visited[k] = true;
                        }
                    }
                }
            }
        }
    }

实验测试:创建测试用图进行测试

时间: 2024-10-01 23:32:43

20162320刘先润大二 实验四 图及应用的相关文章

20162320刘先润大二 实验五 数据结构综合应用

一.分析系统架构 二.编译.运行.测试系统 1.首先进入团队项目的码云? Java演绎法?,点击克隆/下载按钮下的复制 2.打开Android Studio,点击VCS列表下的Git,然后点击clone 3.将复制的地址粘贴到Git Repository URL下,然后选择克隆路径和名称,点击clone,等待克隆完成就相当于编译成功 4.点击run并配置相应的虚拟手机设备,运行截图如下 三.修改系统 1.首先打开主界面的xml文件,进入design模式,从左边添加一个按钮进入任意位置,查看其id

20162328蔡文琛 实验四 图的实现与应用

20162328蔡文琛 大二 实验四 任务详情 实验1 用邻接矩阵实现无向图(边和顶点都要保存),实现在包含添加和删除结点的方法,添加和删除边的方法,size(),isEmpty(),广度优先迭代器,深度优先迭代器 实现类 public class MatrixUDG { private char[] mVexs; // 顶点集合 private int[][] mMatrix; // 邻接矩阵 /* * 创建图(自己输入数据) */ public boolean isEmpty(){ bool

20162304 2017-2018-1 实验四-图的实现与应用

实验四-图的实现与应用 实验四 图的实现与应用-1 试验内容 用邻接矩阵实现无向图(边和顶点都要保存),实现在包含添加和删除结点的方法,添加和删除边的方法,size(),isEmpty(),广度优先迭代器,深度优先迭代器 给出伪代码,产品代码,测试代码(不少于5条测试) 实验结果 要想用邻接矩阵实现图,首先需要使用一个一维数组存放顶点,一个二维数组存放边: 然后清楚两个顶点之间的关系如何表示,用邻接矩阵表示出来是什么样的: 其中值得注意的是对角线上的应该是0,因为自己和自己是没有路径的. 广度优

数据结构实验报告-实验四 图的构造与遍历

实验四   图的构造与遍历   l  实验目的 1.图的的定义和遍历 (1)掌握图的邻接矩阵.邻接表的表示方法. (2)掌握建立图的邻接矩阵的算法. (3)掌握建立图的邻接表的算法. (4)加深对图的理解,逐步培养解决实际问题的能力. l  实验内容 1.图的定义和遍历 (一)基础题 1.编写图基本操作函数: (1)CreateALGraph(ALGraph &G) 建立无向图的邻接表表示: (2)LocateVex(ALGraph &G,char v)图查找信息: (3)DFSTrave

实验四 图的实现和应用 实验报告 20162305

实验四 图的实现和应用 实验报告 20162305 实验一 邻接矩阵实现无向图 实验要求 用邻接矩阵实现无向图(边和顶点都要保存),实现在包含添加和删除结点的方法,添加和删除边的方法,size(),isEmpty(),广度优先迭代器,深度优先迭代器.给出伪代码,产品代码,测试代码(不少于5条测试) 实验过程 用邻接矩阵表示无向图,首先我们先明确什么是邻接矩阵.邻接矩阵就是用矩阵的方式来表示不同结点之间的关系,对于无向图来说,如果结点(i,j)之间有联系,则在矩阵中(i,j)所对应的的点的值为1,

20162313 苑洪铭 实验四 图的实现与应用

20162313 苑洪铭 实验四 图的实现与应用 实验1 要求 用邻接矩阵实现无向图(边和顶点都要保存),实现在包含添加和删除结点的方法,添加和删除边的方法,size(),isEmpty(),广度优先迭代器,深度优先迭代器 给出伪代码,产品代码,测试代码(不少于5条测试) 内容 邻接矩阵(Adjacency Matrix):是表示顶点之间相邻关系的矩阵.设G=(V,E)是一个图,其中V={v1,v2,-,vn}. 对无向图而言,邻接矩阵一定是对称的,而且主对角线一定为零,副对角线不一定为0. 总

2017-2018-1 20162330 实验四 图的实现与应用

课程名称:<程序设计与数据结构> 学生班级:1623班 学生姓名:刘伟康 学生学号:20162330 实验时间:2017年11月20日-2017年11月24日 实验名称:图的实现与应用 指导老师:娄嘉鹏.王志强老师 目录 实验要求 实验步骤及代码实现 代码托管汇总 图的实现与应用-1:用邻接矩阵实现无向图 图的实现与应用-2:用十字链表实现有向图 图的实现与应用-3:实现PP19.9 测试过程及遇到的问题 1. 第一个实验无向图的边输入错误 分析总结及PSP时间统计 参考资料 实验要求: 实验

20162327WJH实验四——图的实现与应用

20162327WJH实验四--图的实现与应用 实 验 报 告 课程:程序设计与数据结构 班级: 1623 姓名: 王旌含 学号:20162327 成绩: 指导教师:娄嘉鹏 王志强 实验日期:11月20日 实验密级: 非密级 预习程度: 已预习 实验时间:15:25-17:15 必修/选修: 必修 实验序号: cs_23 实验内容 实验一 1.实验内容 用邻接矩阵实现无向图(边和顶点都要保存),实现在包含添加和删除结点的方法,添加和删除边的方法,size(),isEmpty(),广度优先迭代器,

实验四 图的遍历算法设计与实现

一.实验名称:图的遍历算法设计与实现 二.实验目的: 1.掌握图的深度优先遍历的算法. 2.掌握图的广度优先遍历的算法. 3.实验章节:算法设计与分析 第四章 三.实验内容.实验问题和程序运行结果 第一部分 广度优先遍历算法 1. 分析Graph类,画出Graph类初始化以后的Graph对象的数据结构图. 2. 分析BFS函数,画出流程图. 3. 上述程序   int data[7][7]={{ 1,-1,-1,-1,-1,-1,-1}, { 6, 3, 2,-1,-1,-1,-1}, { 0,