邻接矩阵存储的图

<span style="font-size:24px;">java实现用邻接矩阵(相邻矩阵)实现图,缺点是矩阵中大量的0元素会耗费大量的存储空间</span>

public class Graph {
    final int MAX_VERTEX = 10;// 最多10个顶点
    Vertex[] vertex;// 顶点数组
    int[][] adjacency;// 邻接矩阵
    int numOfVertex;// 当前图中顶点的数量  

    public Graph() {// 构造器
        vertex = new Vertex[MAX_VERTEX];
        adjacency = new int[MAX_VERTEX][MAX_VERTEX];
        numOfVertex = 0;
        // 将邻接矩阵初始化
        for (int i = 0; i < MAX_VERTEX; i++) {
            for (int j = 0; j < MAX_VERTEX; j++)
                adjacency[i][j] = 0;
        }
    }  

    // 添加顶点
    public void addVertex(char v) {
        vertex[numOfVertex++] = new Vertex(v);
    }  

    //无向图 添加边
    public void addEdge(int start, int end) {
        adjacency[start][end] = 1;
        adjacency[end][start] = 1;
    }
    //有向图添加边
    public void addEdge1(int start,int end){
        adjacency[start][end] = 1;
    }
    // 打印某个顶点
    public void showVertex(int index) {
        System.err.print(vertex[index].label);
    }  

    // 打印邻接矩阵
    public void show() {
        for (int i = 0; i < MAX_VERTEX; i++) {
            for (int j = 0; j < MAX_VERTEX; j++) {
                if (j == MAX_VERTEX - 1)
                    System.out.println(adjacency[i][j] + "  ");
                else
                    System.out.print(adjacency[i][j] + "  ");
            }
        }
    }  

    /**
     * 找到与某一顶点邻接而未被访问的顶点,如何做?
     * 在邻接矩阵中,找到指定顶点所在的行,从第一列开始向后寻找值为1的列,列号是邻接顶点的号码,检查此顶点是否访问过。
     * 如果该行没有值为1而又未访问过的点,则此顶点的邻接点都访问过了。
     */
    public int getUnVisitedVertex(int index) {
        for (int i = 0; i < numOfVertex; i++)
            if (adjacency[index][i] == 1 && vertex[i].wasVisited == false)
                return i;
        return -1;
    }  

    // 图的深度优先遍历
    public void dfs() {
        vertex[0].wasVisited = true;// 从头开始访问
        showVertex(0);
        Stack stack = new Stack();
        stack.push(0);
        /**
         * 1.用peek()方法获取栈顶的顶点 2.试图找到这个顶点的未访问过的邻接点 3.如果没有找到这样的顶点,出栈 4.如果找到,访问之,入栈
         */
        while (!stack.isEmpty()) {
            int index = getUnVisitedVertex(stack.peek());
            if (index == -1)// 没有这个顶点
                stack.pop();
            else {
                vertex[index].wasVisited = true;
                showVertex(index);
                stack.push(index);
            }
        }
        // 栈为空,遍历结束,标记位重新初始化
        for (int i = 0; i < numOfVertex; i++)
            vertex[i].wasVisited = false;
    }  

    // 图的广度优先遍历
    public void bfs() {
        vertex[0].wasVisited = true;
        showVertex(0);
        Queue queue = new Queue();
        queue.insert(0);
        int v2;
        while (!queue.isEmpty()) {// 直到队列为空
            int v1 = queue.remove();
            // 直到点v1没有未访问过的邻接点
            while ((v2 = getUnVisitedVertex(v1)) != -1) {
                // 取到未访问过的点,访问之
                vertex[v2].wasVisited = true;
                showVertex(v2);
                queue.insert(v2);
            }
        }
        for (int i = 0; i < numOfVertex; i++)
            vertex[i].wasVisited = false;
    }  

    // 最小生成树 minimum spanning tree
    public void mst() {
        vertex[0].wasVisited = true;
        Stack stack = new Stack();
        stack.push(0);
        while (!stack.isEmpty()) {
            int currentVertex = stack.peek();
            int v = getUnVisitedVertex(currentVertex);
            if (v == -1)
                stack.pop();
            else {
                vertex[v].wasVisited = true;
                stack.push(v);
                //当前顶点与下一个未访问过的邻接点
                showVertex(currentVertex);
                showVertex(v);
                System.out.print("  ");
            }
        }
        for (int i = 0; i < numOfVertex; i++)
            vertex[i].wasVisited = false;
    }  

    public static void main(String[] args) {
        Graph graph = new Graph();
        graph.addVertex('A');
        graph.addVertex('B');
        graph.addVertex('C');
        graph.addVertex('D');
        graph.addEdge(1, 2);
        graph.addEdge(0, 1);
        graph.addEdge(2, 3);
        graph.show();
//        graph.dfs();
        // graph.bfs();
        //graph.mst();
    }  

}  

// 顶点
class Vertex {
    char label;// 如A,B,C
    boolean wasVisited;// 标识是否访问过此顶点  

    public Vertex(char vertex) {
        this.label = vertex;
        wasVisited = false;
    }
}  

// 栈
class Stack {
    final int MAX_SIZE = 10;
    int stack[];
    int top;  

    public Stack() {
        stack = new int[MAX_SIZE];
        top = -1;
    }  

    public void push(int idata) {
        stack[++top] = idata;
    }  

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

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

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

// 队列
class Queue {
    final int SIZE = 10;
    int[] qarray;
    int front;
    int rear;  

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

    // 在队尾追加
    public void insert(int key) {
        if (rear == SIZE - 1)
            rear = -1;
        qarray[++rear] = key;
    }  

    // 队头删除数据
    public int remove() {
        int temp = qarray[front++];
        if (front == SIZE)
            front = 0;
        return temp;
    }  

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

邻接矩阵存储的图

时间: 2024-10-06 14:51:08

邻接矩阵存储的图的相关文章

基于邻接矩阵存储的图的深度优先遍历和广度优先遍历

图的存储结构相比较线性表与树来说就复杂很多,对于线性表来说,是一对一的关系,所以用数组或者链表均可简单存放.树结构是一对多的关系,所以我们要将数组和链表的特性结合在一起才能更好的存放. 那么我们的图,是多对多的情况,另外图上的任何一个顶点都可以被看作是第一个顶点,任一顶点的邻接点之间也不存在次序关系. 仔细观察以下几张图,然后深刻领悟一下: 因为任意两个顶点之间都可能存在联系,因此无法以数据元素在内存中的物理位置来表示元素之间的关系(内存物理位置是线性的,图的元素关系是平面的). 如果用多重链表

PTA 邻接矩阵存储图的深度优先遍历

6-1 邻接矩阵存储图的深度优先遍历(20 分) 试实现邻接矩阵存储图的深度优先遍历. 函数接口定义: void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) ); 其中MGraph是邻接矩阵存储的图,定义如下: typedef struct GNode *PtrToGNode; struct GNode{ int Nv; /* 顶点数 */ int Ne; /* 边数 */ WeightType G[MaxVertexNum][MaxVe

练习6.1 邻接矩阵存储图的深度优先遍历 (20分)

试实现邻接矩阵存储图的深度优先遍历. 函数接口定义: void DFS( MGraph Graph, Vertex V, void (*Visit)(Vertex) ); 其中MGraph是邻接矩阵存储的图,定义如下: typedef struct GNode *PtrToGNode; struct GNode{ int Nv; /* 顶点数 */ int Ne; /* 边数 */ WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */ }; t

java 数据结构 图中使用的一些常用算法 图的存储结构 邻接矩阵:图的邻接矩阵存储方式是用两个数组来标示图。一个一位数组存储图顶点的信息,一个二维数组(称为邻接矩阵)存储图中边或者弧的信息。 设图G有n个顶点,则邻接矩阵是一个n*n的方阵,定义为: 实例如下,左图是一个无向图。右图是邻接矩阵表示:

以下内容主要来自大话数据结构之中,部分内容参考互联网中其他前辈的博客. 图的定义 图是由顶点的有穷非空集合和顶点之间边的集合组成,通过表示为G(V,E),其中,G标示一个图,V是图G中顶点的集合,E是图G中边的集合. 无边图:若顶点Vi到Vj之间的边没有方向,则称这条边为无项边(Edge),用序偶对(Vi,Vj)标示. 对于下图无向图G1来说,G1=(V1, {E1}),其中顶点集合V1={A,B,C,D}:边集合E1={(A,B),(B,C),(C,D),(D,A),(A,C)}: 有向图:若

图的邻接矩阵存储数据结构--自己写数据结构

头文件graph.h #ifndef _GRAPH_H_ #define _GRAPH_H_ #define MAX_VER 100 #define ENDLESS 65535 typedef char VertexType; typedef int EdgeType; typedef struct _Graph { VertexType ver[MAX_VER]; EdgeType edge[MAX_VER][MAX_VER]; int num_ver,num_edge; }Graph,*pG

图的邻接矩阵存储

邻接表的构造与邻接矩阵完全不同,同学们应该发现了,邻接表的的结构更像是由几个链表构成的. 在构造邻接表时,我们的确会借助链表的结构.对图中每个顶点的信息,我们都会分别使用一个链表来进行存储. 因此,我们需要初始化一个有 n 个元素的链表数组,n 为图中顶点数量. 我们要在邻接表中存储的图的信息,实际上就是顶点之间存在的有向边. 当从顶点 a 到顶点 b 存在一条有向边时,我们只需要在头结点为 a 的链表后插入一个结点 b. 值得注意的是,当一条边是从顶点 b 到顶点 a 时,我们同样需要在以 b

图的操作和l邻接矩阵存储

/* 1.图是由顶点集合及顶点之间的关系集合组成的一种数据结构.图的定义:G=(V,E) 2.顶点和边:图中的结点一般称作顶点,顶点与顶点相关联称作遍 3.完全图:在n个顶点的无向图中,若有n(n-1)/2条边,即任意两个顶点之间有且只有一条边,则称此图 为无向完全图:在n个顶点的右向图中,若有n(n-1)条边,即任意两个顶点之间有且只有方向相反的2条边, 则称此图为有向完全图. 4.顶点的度:顶点的度=出度+入度 5.连通图和强连通图: 在无向图中,若从顶点vi到顶点vj有路径,则称顶点vi和

DS图—图的邻接矩阵存储及度计算

题目描述 假设图用邻接矩阵存储.输入图的顶点信息和边信息,完成邻接矩阵的设置,并计算各顶点的入度.出度和度,并输出图中的孤立点(度为0的顶点) --程序要求-- 若使用C++只能include一个头文件iostream:若使用C语言只能include一个头文件stdio 程序中若include多过一个头文件,不看代码,作0分处理 不允许使用第三方对象或函数实现本题的要求 输入 测试次数T,每组测试数据格式如下: 图类型  顶点数 (D—有向图,U—无向图) 顶点信息 边数 每行一条边(顶点1 顶

邻接矩阵存储简单路径(swust oj 1070)

Description 假设无向图G采用邻接矩阵存储,设计一个算法,输出图G中从顶点u到v的所有简单路径. Input 简单路径是指路径上的顶点不重复.第一行为一个整数n,表示顶点的个数(顶点编号为0到n-1),第二行表示顶点u和v的编号,接下来是为一个n*n大小的矩阵,表示图的邻接关系.数字为0表示不邻接,1表示不邻接. Output 输出图G中从顶点u到v的所有简单路径. Sample Input 5 0 3 0 1 0 1 1 1 0 1 1 0 0 1 0 1 1 1 1 1 0 1 1