图之邻接矩阵

核心思想:利用两个数组分别存储数据元素(顶点)的信息和数据元素之间关系(弧或边)的信息。其中,顶点信息用一维数组表示,关系信息用二维数组表示。
无向图:顶点Vi的度是邻接矩阵中第i(或第i列)的元素之和;
有向图:第i行的元素之和是顶点Vi的出度;第j列的元素之和是顶点Vj的入度;
缺点:存储空间相对而言比较大,n个顶点,n^2个边;

下面给出图的邻接矩阵存储结构的Java实现:

package org.sky.graph;

import java.util.ArrayList;
/**
 * @Description 利用邻接矩阵表示无向图(有向图)
 * @author sky
 * @date 2016/12/27
 */
public class AdjacencyMatrixGragh {

    @SuppressWarnings("rawtypes")
    private ArrayList vertices = null;  //存放顶点
    private int[][] edgeMatrix = null;  //邻接矩阵

    @SuppressWarnings("unused")
    private int numEdge = 0;        //边数目
    private int numVertices = 0;    //顶点数目

    private int maxWeight = Integer.MAX_VALUE;  //两顶点间无通路时,相应边赋值为maxWeight

    @SuppressWarnings("rawtypes")
    public AdjacencyMatrixGragh(int size){
        this.vertices = new ArrayList(size);
        this.edgeMatrix = new int[size][size];
        for(int i = 0; i < size; i++){      //initialize edgeMatrix
            for(int j = 0; j < size; i++){
                edgeMatrix[i][j] = (i == j) ? 0 : maxWeight;
            }
        }
    }

    /**
     * 扩展顶点及邻接矩阵
     */
    @SuppressWarnings("unchecked")
    public void expand(){
        @SuppressWarnings("rawtypes")
        ArrayList vLarger = new ArrayList(vertices.size() * 2);
        int[][] eLarger = new int[vLarger.size()][vLarger.size()];
        for(int i = 0; i < vertices.size(); i++){
            vLarger.set(i, vertices.get(i));
            for(int j = 0; j < vertices.size(); j++){
                eLarger[i][j] = edgeMatrix[i][j];
            }
        }
        vertices = vLarger;
        edgeMatrix = eLarger;
    }

    /**
     * 获取顶点v的第一个邻接顶点的位置
     * @param v
     * @return 存在,返回相应位置;否则,返回-1
     */
    public int getFirstNeighbor(int v){
        if(v != -1){
            for(int col = 0; col < numVertices; col++){
                if(edgeMatrix[v][col] > 0 && edgeMatrix[v][col] < maxWeight){
                    return col;
                }
            }
        }
        return -1;
    }

    /**
     * 获取顶点在图中的位置
     * @param vertex
     * @return 存在,返回相应位置;否则,返回-1
     */
    public int getVertexPosition(Object vertex){
        for(int i = 0; i < numVertices; i++){
            if(vertices.get(i) == vertex){
                return i;
            }           
        }
        return -1;
    }

    /**
     * 获取位置i处的顶点
     * @param i
     * @return 存在,返回相应结点信息;否则,返回0
     */
    public Object getValue(int i){
        return i >= 0 && i < numVertices ? vertices.get(i) : null;
    }

    /**
     *获取边(v1, v2)上的权值
     * @param v1
     * @param v2
     * @return 存在,返回相应边的权值;否则,返回0
     */
    public int getWeight(int v1, int v2){
        return v1 != -1 && v2 != -1 ? edgeMatrix[v1][v2] : 0;
    }

    /**
     * 在指定两点间添加一条边
     * @param start
     * @param end
     * @param len
     */
    public void addEdge(int start, int end, int len){
        edgeMatrix[start][end] = len;
        edgeMatrix[end][start] = len;
        numEdge ++;
    }

    /**
     * 删除指定两点间的一条边
     * @param start
     * @param end
     */
    public void removeEdge(int start, int end){
        edgeMatrix[start][end] = 0;
        edgeMatrix[end][start] = 0;
        numEdge --;     
    }

    /**
     * 添加顶点
     * @param element
     */
    @SuppressWarnings("unchecked")
    public void addVertex(Object element){
        if(numVertices == vertices.size()){
            expand();
        }
        vertices.set(numVertices ++, element);
    }

    /**
     * 删除顶点。并返回该顶点的值
     * @param position
     * @return 顶点的值
     */
    @SuppressWarnings("unchecked")
    public Object removeVertex(int position){
        Object result = vertices.get(position);
        int size = vertices.size();

        for(int i = 0; i < size; i++){  //将关系矩阵向内紧缩
            for(int j = 0; j < size; j++){
                if(i > position && j > position){
                    edgeMatrix[i-1][j-1] = edgeMatrix[i][j];
                }else if(i > position){
                    edgeMatrix[i-1][j] = edgeMatrix[i][j];
                }else if(j > position){
                    edgeMatrix[i][j-1] = edgeMatrix[i][j];
                }
            }
        }       
        for(int i = 0; i <size; i++){   //最后一个顶点紧缩后无意义,赋值为0;
            edgeMatrix[size - 1][i] = 0;
            edgeMatrix[i][size - 1] = 0;
        }

        for(int i = position; i < size -1; i++){ //相应调整顶点信息
            vertices.set(i, vertices.get(i+1));
        }       
        vertices.set(size-1, null);
        numVertices--;

        return result;
    }
}

参考文献:
图的邻接矩阵实现
图的Java实现(邻接矩阵)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值