数据结构(C++)<图的邻接矩阵存储>

来源:互联网 发布:mac pro 显卡升级 编辑:程序博客网 时间:2024/04/30 10:42

1.图的概念

图是有顶点集合以及顶点的关系集合组成的一种数据结构。
a)完全图:由n个顶点组成的无向图,若有n*(n-1)/2条边,则称为无向图完全图。
在由n个顶点组成的有向图中,若有n*(n-1)条边,则称之为有向完全图。
b)权:在某些图中,边具有与之相关的数值,称为权重。权重可以表示从一个顶点到另一个顶点的距离、花费的代价等等。这种带权图也叫作网络。
c)度:与顶点v关联的边数称为度。在有向图中顶点的度数等于其入度加出度之和。入度是指以结点为终点的边 ,出度是指以结点为起点的边。
d)连通图:
在图论中,连通图基于连通的概念。在一个无向图 G 中,若从顶点vi到顶点vj有路径相连(当然从vj到vi也一定有路径),则称vi和vj是连通的。如果 G 是有向图,那么连接vi和vj的路径中所有的边都必须同向。如果图中任意两点都是连通的,那么图被称作连通图。如果此图是有向图,则称为强连通图(注意:需要双向都有路径)。
e)连通分量:连通分量:无向图 G的一个极大连通子图称为 G的一个连通分量(或连通分支)。连通图只有一个连通分量,即其自身;非连通的无向图有多个连通分量。

2.邻接矩阵:

所谓邻接矩阵(Adjacency Matrix)的存储结构,就是用一维数组存储图中顶点的信息,用矩阵表示图中各顶点之间的邻接关系。假设图G=(V,E)有n 个确定的顶点,即V={v0,v1,…,vn-1},则表示G 中各顶点相邻关系为一个n×n 的矩阵,矩阵的元素为:

这里写图片描述

用邻接矩阵表示法表示图如图8.7 所示:
这里写图片描述
3.代码 实现:
Graphmtx.h

#ifndef GRAPHMTX_H#define GRAPHMTX_H#include<Graph.h>#include<iostream>#include<stdlib.h>using namespace std;template <class T,class E>class Graphmtx{public:    E maxWeight;    /** Default constructor */    Graphmtx(int sz=DefaultVertices)    {        maxVertices=sz;        numVertices=0;        numEdges=0;        VerticesList =new T[maxVertices];        Edge =(E **)new E *[maxVertices];        //初始化邻接矩阵        for(int i=0; i<maxVertices; i++)            Edge[i]=new E[maxVertices];        for(int i=0; i<maxVertices; i++)            for(int j=0; j<maxVertices; j++)                Edge[i][j]=i==j?0:maxWeight;    }    /** Default destructor */    ~Graphmtx()    {        delete []VerticesList;        delete Edge;    }    //当前定点数    int NumberOfvertices()    {        return numVertices;    }    //返回当前边数    int NumberOfEdges()    {        return numEdges;    }//获取顶点的值    T getValue(int i)    {        return i>=0&&i<numVertices?VerticesList[i]:NULL;    }    //获取边上的权值    E getWeight(int v1,int v2)    {        return -1!=v1&&-1!=v2?Edge[v1][v2]:0;    }    //获取顶点v的第一个邻接顶点    int getFirstNeighbor(int v)    {        if(-1!=v)        {            for(int col=0; col<numVertices; col++)                if(Edge[v][col]>0&&Edge[v][col]<maxWeight)                    return col;        }        return -1;    }    //获取v的邻接顶点w的下一邻接顶点    int getNextNeighbor(int v,int w)    {        if(-1!=v&&-1!=w)            for(int col=w+1; col<maxVertices; col++)                if(Edge[v][col]>0&&Edge[v][col]<maxWeight)                    return col;        return -1;    }    //插入顶点    bool insertVertex(const T &vertex)    {        if(numVertices==maxVertices)            return false;        VerticesList[numVertices++]=vertex;        return true;    }    //插入边    bool insertEdge(int v1,int v2,const E cost)    {        if(v1>-1&&v1<numVertices&&v2>-1&&v2<numVertices&&Edge[v1][v2]==maxWeight)        {            Edge[v1][v2]=Edge[v2][v1]=cost;            numEdges++;            return true;        }        return false;    }    //删除顶点v以及所有与之关联的边    bool removeVertex(int v)    {        //v不在图中不删除        if(v<0||v>numVertices)            return false;        //只剩下一个顶点,不删除        if(1==numVertices)        {            return false;        }        VerticesList[v]=VerticesList[numVertices-1];        //减去与v相关联的边        for(int i=0; i<numVertices; i++)            if(Edge[v][i]>0&&Edge[v][i]<maxWeight)                numEdges--;        //用最后一列填补第        for(int i=0; i<numVertices; i++)            Edge[i][v]=Edge[i][numVertices-1];        numVertices--;        //用最后一行填补第v行        for(int i=0; i<numVertices; i++)            Edge[v][i]=Edge[numVertices-1][i];        return true;    }    //删除边(v1,v2)    bool removeEdge(int v1,int v2)    {        if(v1>-1&&v1<numVertices&&v2>-1&&v2<numVertices&&Edge[v1][v2]>0&&Edge[v1][v2]<maxWeight)        {            Edge[v1][v2]=Edge[v2][v1]=maxWeight;            numEdges--;            return true;        }        return false;    }    template <class V,class W>    friend istream& operator >>(istream & in,Graphmtx<V,W> &G);    template <class V,class W>    friend ostream& operator<<(ostream &out,Graphmtx<V,W> &G);private:    //最大的顶点树    int maxVertices;    //当前边数    int numEdges;    //当前顶点树    int numVertices;    //顶点表    T *VerticesList;    //邻接矩阵    E **Edge;    //给出顶点在图中的位置    int getVertexPos(T vertex)    {        for(int i=0; i<numVertices; i++)        {            if(VerticesList[i]==vertex)                return i;        }        return -1;    }};#endif // GRAPHMTX_H

main.cpp

#include <iostream>#include<Graphmtx.h>using namespace std;int main(){    Graphmtx<int,int> G(5);    cin>>G;    cout<<G;    return 0;}template <class V,class W>istream& operator >>(istream & in,Graphmtx<V,W> &G){    //n是顶点数,m是边数    int n,m;    V e1,e2;    W weight;    cout<<"请输入顶点数、边数:"<<endl;    in>>n>>m;    cout<<"请输入顶点:"<<endl;    for(int i=0; i<n; i++)    {        in>>e1;        G.insertVertex(e1);    }    int i=0,j,k;    cout<<"请输入边的两个顶点以及权值:"<<endl;    while(i<m)    {        in>>e1>>e2>>weight;        j=G.getVertexPos(e1);        k=G.getVertexPos(e2);        if(-1==j&&-1==k)        {            cout<<"边的两端信息有误,请重新输入。"<<endl;        }        else        {            G.insertEdge(j,k,weight);            i++;        }    }    return in;}template <class V,class W>ostream& operator<<(ostream &out,Graphmtx<V,W> &G){//输出所有顶点和边的信息    int n,m;    V e1,e2;    W w;    n=G.NumberOfvertices();    m=G.NumberOfEdges();    out<<"一共有顶点数:"<<n<<"个    边:"<<m<<"条"<<endl;    for(int i=0; i<n; i++)        for(int j=i+1; j<n; j++)        {            w=G.getWeight(i,j);            if(w>0&&w<G.maxWeight)            {                e1=G.getValue(i);                e2=G.getValue(j);                out<<"("<<e1<<","<<e2<<","<<w<<")"<<endl;            }        }    return out;}

这里写图片描述
工程源码请点击我的GitHub

0 0
原创粉丝点击