7、创建图及图的遍历(java实现)

1、顺序表用于图的深度优先遍历

public class SeqList {

    public final int MaxSize = 10;

    public Object list[];
    public int size;

    /**
     * 初始化
     */
    public SeqList() {
        list = new Object[MaxSize];
        this.size = 0;
    }

   /* public SeqList initSeqList(SeqList seqList) {
        seqList.list = new Object[MaxSize];
        seqList.size = 0;
    }*/

    public boolean isFull(SeqList list) {
        if (list.size >= MaxSize) {
            return true;
        }
        return false;
    }

    public boolean isEmpty(SeqList list) {
        if (list.size <= 0) {
            return true;
        }
        return false;
    }

    public void insertList(SeqList seqList, int i, Object data) {
        if (isFull(seqList)) {
            System.out.println("已满无法插入");
            return;
        } else if (i < 0 || i > seqList.size) {
            System.out.println("您输入的位置有问题");
            return;
        }

        for (int j = seqList.size; j > i; j--) {
            seqList.list[j] = seqList.list[j - 1];
        }

        seqList.list[i] = data;
        seqList.size++;
    }

    public void deleteList(SeqList seqList, int i) {
        if (isEmpty(seqList)) {
            System.out.println("已空,没有元素可删除");
            return;
        } else if (i < 0 || i >= seqList.size) {
            System.out.println("您输入的位置参数有问题");
            return;
        }

        for (int j = i+1; j <= seqList.size - 1; j++) {
            seqList.list[j-1] = seqList.list[j];
        }
        seqList.size--;
    }

    public int getSize(SeqList seqList) {
        return  seqList.size;
    }

    public Object getData(SeqList seqList, int i) {
        if (isEmpty(seqList)){
            System.out.println("已空没有可取元素");
            return null;
        }else if(i<0 || i>= seqList.size){
            System.out.println("您给的位置有问题");
            return null;
        }

        return seqList.list[i];
    }

    public void printf(SeqList seqList) {
        if (isEmpty(seqList)){
            System.out.println("已空,无需遍历");
            return;
        }

        for (int i = 0; i < seqList.size; i++) {
            System.out.print(seqList.list[i] + " ");
        }
    }

    public static void main(String[] args) {
        SeqList seqList = new SeqList();

        System.out.println("元素个数: "+  seqList.getSize(seqList));
        seqList.printf(seqList);
        for (int i = 0; i < seqList.MaxSize; i++) {
            seqList.insertList(seqList,i,i);
        }

        seqList.deleteList(seqList,0);

        seqList.insertList(seqList,0,10);
        System.out.println("元素个数: "+  seqList.getSize(seqList));
        seqList.printf(seqList);

    }

}

2、创建顺序队列用户广度优先遍历

public class SeqQueue {

    public final int MaxSize = 8;

    public Object seqqueue[];
    public int front; // 队头
    public int rear;
    public int size;

    public SeqQueue() {
        this.size = 0;
        this.rear = 0;
        this.front = 0;
        this.seqqueue = new Object[MaxSize];
    }

    public boolean isFull(SeqQueue seqQueue) {
        if (seqQueue.size > 0 && seqQueue.rear == seqQueue.front) {
            return true;
        }
        return false;
    }

    public boolean isEmpty(SeqQueue seqQueue) {
        if (seqQueue.size <= 0) {
            return true;
        }
        return false;
    }

    public void queueAppend(SeqQueue seqQueue, Object data) {
        if (isFull(seqQueue)) {
            System.out.println("已满无法插入");
            return;
        }
        seqQueue.seqqueue[seqQueue.rear] = data;
        seqQueue.rear = (seqQueue.rear + 1) % MaxSize;
        seqQueue.size++;
    }

    public Object queueDelete(SeqQueue seqQueue) {
        if (isEmpty(seqQueue)) {
            System.out.println("已空");
            return null;
        }
        Object x = seqQueue.seqqueue[seqQueue.front];

        seqQueue.front = (seqQueue.front + 1) % MaxSize;
        seqQueue.size--;
        return x;
    }

    public static void main(String[] args) {
        SeqQueue seqQueue = new SeqQueue();
        seqQueue.queueDelete(seqQueue);

        for (int i = 0; i < 9; i++) {
            seqQueue.queueAppend(seqQueue, i);
        }

       for (int i = 0; i < 8; i++) {
           System.out.println( seqQueue.queueDelete(seqQueue) + " ");
           ;
        }

    }
}

3、创建需要插入的图信息类

public class CreateE {
    public int row; //行下标
    public int col; //列下标
    public  int weight; // 权重

    public CreateE() {
    }

    public CreateE(int row, int col, int weight) {
        this.row = row;
        this.col = col;
        this.weight = weight;
    }
}

4、图的实现

/**
 * 图的邻接矩阵实现
 *      —— Wij     (vi,vj)或<vi,vj>
 *      |
 * aij = —— 无穷    i != j
 *     |
 *     —— 0       i = j
 */
public class Graph {

    public final int MaxWeight = 1000; //定义为无穷大(用于存储)
    public final int MaxVertices = 10; //顶点的最大值

    SeqList vertices;  //存放顶点的顺序表
    int edge[][];      //存放边的邻接矩阵
    int numberedge;    //边的条数

    public Graph() {
        edge = new int[MaxVertices][MaxVertices]; //初始化边的最大数组(这个和顺序表差不多)
    }

    /**
     * @param graph :要初始化的图
     * @param n     :给图分配几个顶点
     */
    public Graph initGraph(Graph graph, int n) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i == j) {
                    graph.edge[i][j] = 0; //对角线全为0
                } else {
                    graph.edge[i][j] = MaxWeight; //无穷大
                }
            }
        }

        graph.numberedge = 0;  //初始边条数0
        graph.vertices = new SeqList();  //顶点顺序表初始化

        return graph;
    }

    /**
     * 插入顶点
     *
     * @param graph  :需要插入顶点的图
     * @param vertex :插入的顶点值
     */
    public void insertVertex(Graph graph, Object vertex) {
        graph.vertices.insertList(graph.vertices, graph.vertices.size, vertex);
    }

    /**
     * 插入边
     *
     * @param graph  : 需要插入边的图
     * @param vi     :边的一个顶点
     * @param vj     :边的另一顶点
     * @param weight :边上的权重
     */
    public void insertEdge(Graph graph, int vi, int vj, int weight) {
        if (vi < 0 || vi >= graph.vertices.size || vj < 0 || vj >= graph.vertices.size) {
            System.out.println("参数vi,vj越界");
            return;
        }
        graph.edge[vi][vj] = weight;
        graph.numberedge++;
    }

    /**
     * 删除边
     * @param graph : 需要处理的图
     * @param vi :顶点i
     * @param vj : 顶点j
     */
    public void deleteEdge(Graph graph,int vi,int vj) {
        if (vi < 0 || vi >= graph.vertices.size || vj < 0 || vj >= graph.vertices.size) {
            System.out.println("参数vi,vj越界");
            return;
        }else if(graph.edge[vi][vj] == MaxWeight || vi == vj){
            System.out.println("边不存在");
            return;
        }
        graph.edge[vi][vj] = MaxWeight;
        graph.numberedge--;
    }

    /**
     * 创建图
     * @param graph :要创建的图
     * @param V :顶点
     * @param n :d顶点个数
     * @param E :边
     * @param e :边的个数
     */
    public void CreateGraph(Graph graph,Object V[],int n,CreateE E[],int e) {
        for (int i = 0; i < n; i++) {
            graph.insertVertex(graph,V[i]);
        }
        for (int i = 0; i < e; i++) {
            graph.insertEdge(graph,E[i].row,E[i].col,E[i].weight);
        }
    }

    /**
     * 获取图的边的条数
     * @param graph : 需要操作的图
     */
    public void getNumberEdge(Graph graph) {
        if (graph == null){
            System.out.println("该图不存在");
            return;
        }
        System.out.println("边的条数: " + graph.numberedge);
    }

    /**
     * 取第一个邻接顶点
     * @param graph :将要操作的图
     * @param v : 某个顶点开始的第一个邻接顶点
     * @return :找到返回邻接顶点下标,找不到反回-1,错误返回-1
     */
    public int getFirstVex(Graph graph, int v) {
        if (v < 0 || v >= graph.vertices.size) {
            System.out.println("获取第一个邻接顶点参数有问题");
            return -1;
        }
        for (int col = 0; col < graph.vertices.size; col++) {
            if (graph.edge[v][col] > 0 && graph.edge[v][col] < MaxWeight){ //找到本顶点的二位数组中大与0小于无穷的第一个值,就是第一个邻接顶点
                return col;
            }
        }
        return -1;
    }

    /**
     * 获取下一连接顶点
     * @param graph :需要操作的图
     * @param v1 :第一个顶点
     * @param v2 :第一个顶点的邻接顶点
     */
    public int getNextVex(Graph graph,int v1,int v2) {
        if (v1 <0 || v1 >= graph.vertices.size || v2 <0 || v2 >= graph.vertices.size){
            System.out.println("您要获取的下一邻接顶点参数有问题");
            return -1;
        }
        for (int col = v2 + 1; col < graph.vertices.size; col++) {
            if (graph.edge[v1][col] >0 && graph.edge[v1][col] < MaxWeight){
                return col;
            }
        }
        return  -1;
    }

    /**
     * 连通图的深度优先遍历
     * @param graph 需要操作的图
     * @param v : 以某个顶点开始遍历
     * @param visited  :改点是否被访问
     */
    public void DepthSearch(Graph graph,int v,int visited[]) {
        System.out.print(graph.vertices.list[v] + " ");  //先打印第一个访问的顶点
        visited[v] = 1 ; //让改点为已经访问过 1 :访问过 0 : 未访问

        int col = graph.getFirstVex(graph,v);  //获取访问顶点的下一顶点

        while (col != -1){   //如果该节点存在
            if (visited[col] == 0){
                graph.DepthSearch(graph,col,visited);
            }
            col = graph.getNextVex(graph,v,col);
        }
    }

    /**
     * 非连通图的深度优先遍历
     */
    public void DepthFirstSearch(Graph graph) {
        int visited[] = new int[graph.vertices.size];
        for (int i = 0; i < graph.vertices.size; i++) {
            visited[i] = 0; //未访问标记初始值为0
        }
        for (int i = 0; i < graph.vertices.size; i++) {
            if (visited[i] == 0){
                graph.DepthSearch(graph,i,visited);
            }
        }
    }

    /**
     * 连通图的广度优先遍历
     * @param graph
     * @param v
     * @param visited
     */
    public void BroadSearch(Graph graph,int v,int visited[]) {
        SeqQueue seqQueue = new SeqQueue();
        System.out.print(graph.vertices.list[v]+" ");
        visited[v] = 1;
        seqQueue.queueAppend(seqQueue,v);   //初始顶点入队
        while (!seqQueue.isEmpty(seqQueue)){   //队列未空
            int n  = (int)seqQueue.queueDelete(seqQueue);
            int col = graph.getFirstVex(graph,n);
            while (col != -1){
                if (visited[col] == 0){
                    System.out.print(graph.vertices.list[col] + " ");
                    visited[col] = 1;    //设为已访问
                    seqQueue.queueAppend(seqQueue,col);   //邻接顶点入队
                }
                col = graph.getNextVex(graph,n,col);
            }

        }
    }

    public void BroadFirstSearch(Graph graph) {
        int visited[] = new int[graph.vertices.size];
        for (int i = 0; i < graph.vertices.size; i++) {
            visited[i] = 0; //访问标记初始为0
        }
        for (int i = 0; i < graph.vertices.size; i++) {
            if (visited[i] == 0){
                BroadSearch(graph,i,visited);
            }
        }
    }

    public static void main(String[] args) {
        Graph graph = new Graph();
        int n = 6,e=6;
        graph.initGraph(graph,n);

        Object V[] = {‘A‘,‘B‘,‘C‘,‘D‘,‘E‘,‘F‘};

        CreateE E[] = {new CreateE(0,1,10),new CreateE(0,4,20),new CreateE(1,3,30),new CreateE(2,1,40),new CreateE(3,2,50),new CreateE(0,5,30)};

        graph.CreateGraph(graph,V,n,E,e);

        System.out.print("顶点集合:");
        for (int i = 0; i < graph.vertices.size; i++) {
            System.out.print(graph.vertices.list[i]+ " ");
        }
        System.out.println();

        System.out.println("权值集合");
        for (int i = 0; i < graph.vertices.size; i++) {
            for (int j = 0; j < graph.vertices.size; j++) {
                System.out.print(graph.edge[i][j]+"\t\t");
            }
            System.out.println();
        }
        graph.getNumberEdge(graph);

        System.out.println("取第一个邻接顶点 : " + graph.vertices.list[graph.getFirstVex(graph,0)]); //这里取不到就会报错哦。因为取不到,我这设置返回-1
        System.out.println("取下一个邻接顶点 : " +graph.vertices.list[graph.getNextVex(graph,0,graph.getFirstVex(graph,0))]);

        System.out.print("图的深度优先遍历 :");

        graph.DepthFirstSearch(graph);
        System.out.println();

        System.out.print("图的广度优先遍历 :");

        graph.BroadFirstSearch(graph);
        System.out.println();
        graph.deleteEdge(graph,0,1);
        graph.getNumberEdge(graph);
        System.out.println("权值集合");
        for (int i = 0; i < graph.vertices.size; i++) {
            for (int j = 0; j < graph.vertices.size; j++) {
                System.out.print(graph.edge[i][j]+"\t\t");
            }
            System.out.println();
        }

    }

}

5、实现结果

顶点集合:A B C D E F
权值集合
0        10        1000        1000        20        30
1000        0        1000        30        1000        1000
1000        40        0        1000        1000        1000
1000        1000        50        0        1000        1000
1000        1000        1000        1000        0        1000
1000        1000        1000        1000        1000        0
边的条数: 6
取第一个邻接顶点 : B
取下一个邻接顶点 : E
图的深度优先遍历 :A B D C E F
图的广度优先遍历 :A B E F D C
边的条数: 5
权值集合
0        1000        1000        1000        20        30
1000        0        1000        30        1000        1000
1000        40        0        1000        1000        1000
1000        1000        50        0        1000        1000
1000        1000        1000        1000        0        1000
1000        1000        1000        1000        1000        0    

原文地址:https://www.cnblogs.com/karrya/p/11225832.html

时间: 2024-11-05 04:56:04

7、创建图及图的遍历(java实现)的相关文章

数据结构算法之图的存储与遍历(Java)

一:图的分类 1:无向图 即两个顶点之间没有明确的指向关系,只有一条边相连,例如,A顶点和B顶点之间可以表示为 <A, B> 也可以表示为<B, A>,如下所示 2:有向图 顶点之间是有方向性的,例如A和B顶点之间,A指向了B,B也指向了A,两者是不同的,如果给边赋予权重,那么这种异同便更加显著了 =============================================================================================

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

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

邻接矩阵(以顶点为中心),比较稀疏时,采用邻接表;图的两种遍历(邻接矩阵实现)

对于边比较稠密的图,可以采用邻接矩阵(以顶点为中心)的方式表示,而边比较稀疏时,采用邻接表的结构更合适.两种都不能直观表达哪两个点相连或者最短路径是什么. 深度优先遍历类似于树的先根序遍历.与树不同的是,它需要对已经访问过的节点添加标记以免被重复遍历. public class Depth { /** * 对k号节点深度遍历 * @param a * @param color * @param k 节点 */ public static void depthTraversal(int[][] a

如何:从代码创建 UML 类图(ZZ)

您拖动的一个或多个类将显示在关系图上. 它们依赖的类将显示在"UML 模型资源管理器"中. 参见 模型表示类型的方式. 将程序代码中的类添加到 UML 模型 打开一个 C# 项目. 将一个 UML 类图.解决方案: 在"体系结构"菜单上,选择"新建关系图". 在"添加新关系图"对话框中选择"UML 类图". 如果您还没有,将建模项目创建. 打开"体系结构资源管理器": 在"体系

如何在Ubuntu 16.04中创建GIF动图

导读 FFmpeg 是一款开源的音.视转换器,使用 FFmpeg 我们可以非常容易地转换和录制音视频文件,而 ImageMagick 是一款用于创建.编辑和合并位图图像的一款开源软件. 大家经常在新浪微薄.QQ.facebook.twitter 中看到有趣的 GIF 动图吧,GIF 文件比视频小.比静态 JPG 图片形像生动,非常适于互联网上的搞笑帖子.产品展示和功能步骤演示,所以此小教程将教大家如何在 Ubuntu 16.04 LTS 桌面系统中制作.转换 GIF 效果图片.其实并不难,只需一

如何快速使用MindManager快速创建思维导图模板

绘制一幅完整的思维导图第一步就是要开始新建一个导图,MindManager提供了多种方式帮助用户新建导图,包括新建空白导图.使用模板创建导图以及从外面导入文件等等,本文将简要介绍五种方式教您如何新建MindManager思维导图. 选项一 创建空白思维导图 通过以下4种方式可以快速创建一个空白的MindManager思维导图模板,导图的中心主题为Central Topic,单击模块即可添加主题信息,然后点击Enter键即可创建其他主题. · 双击底部工作簿标签栏附近空白区域 · 通过快速访问工具

如何创建CAD外部图块

我们在CAD绘图设计的时候,常常会遇到CAD图块的创建的相关问题,其中创建CAD外部图块就是很常见的问题之一.例如我们在一张图纸绘制的时候使用过的图块,可能在其他图纸绘制的时候也需要重复使用,这时候则需要创建外部图块,也就是永久块.外部图块不依赖于当前图形,可以在任意图形文件中调用并且插入.小编今天就给大家演示一下,如何创建CAD外部图块的具体步骤.演示步骤如下:步骤一:执行"WBLOCK"命令1.首先我们运行迅捷CAD编辑器专业版,在绘图窗口里,我们绘制出一个需要长久使用的图形(这里

模板 - 图论 - 图的存储和遍历

链式前向星法存的带边权的图,(尤其在多组数据时)时间效率比vector略高且节省空间,缺点是不容易对一个点的出边进行排序去重,当平行边无所谓时选择这个方法是非常明智的.链式前向星法存图的最大的问题是要记得给反向边预留空间. 图的存储和遍历,在图中搜索树的父子关系其实一般不是很重要.注意下面的代码是没有对vis进行清空的,因为其实并不是每次搜索前都会需要清空,有时候有一些其他的操作(特别是有向图).需要管边权的去找dijkstra算法就好了. struct Graph { static const

matlab画一个局部放大的图中图(总结再总结)

转自http://blog.sina.com.cn/s/blog_4d7c97a00101i7k5.html 照旧感谢原作者,分享者们,阿门! 以下三种方法,szlqq345喜欢用第一种的. 第一种:magnify是个动态放大镜,固化后可以用tools>edit plot移动小图,能选取多个局部图,这个方法不错 用法:打开figure图,输入magnify,左键动态选取查看,ctrl+左键固化,也可右键固化,‘<’和‘>’缩放方法范围,‘+’和‘-’缩放放大比例 原帖:http://ww