基于相邻矩阵实现图的ADT
相邻矩阵表示法:
(1)也也称邻接矩阵或二维数组表示发
(2)图的顶点元素是一个|V|的顺序表
(3)如果从vi到vj存在一条边,则第i行的第j个元素做标记,否则不做标记
(4)如果矩阵中的元素要存储边的权值,则矩阵中每个元素必须足够大(存储权值),或者存储一个指向权值存储位置的指针
相邻矩阵特点分析:
(1)可以用于存储无向图或者有向图
(2)相邻矩阵需要存储所有可能的边,不管这条边是否实际存在
(3)没有结构性开销,但是存在空间浪费
(4)相邻矩阵的空间代价只与顶点的个数有关,为O(|V|^2),图越密集,其空间效率就越高
(5)基于相邻矩阵的图算法,必须查看它的所有可能的边,导致总的时间代价为O(|V|^2),所以相邻矩阵适合密集图的存储
图的ADT:
图的基本操作:
(1)结构操作/销毁型操作
(2)引用型操作:
获取图顶点或边,查找
(3)加工型操作:
插入,删除图顶点或边
图ADT代码:Graph.hpp
1 #ifndef _GRAPH_HPP_ 2 #define _GRAPH_HPP_ 3 #define VertexType int 4 class Graph{ 5 public: 6 virtual int n()=0; 7 virtual int e()=0; 8 virtual int first(int )=0; 9 virtual int next(int,int)=0; 10 virtual void putVex(int v,VertexType value)=0; 11 virtual int locateVex(VertexType u)=0; 12 virtual VertexType getVex(int v)=0; 13 virtual void setEdge(int v1,int v2,int value)=0; 14 virtual void deleteEdge(int,int)=0; 15 virtual void setMark(int v,int value)=0; 16 virtual int getMark(int v)=0; 17 virtual int getEdge(int,int )=0; 18 }; 19 #endif
图ADT的物理实现-相邻矩阵
声明:Graphm.hpp
1 #ifndef _GRAPHM_HPP_ 2 #define _GRAPHM_HPP_ 3 #define VertexType int 4 #define MAX_VERTEX_NUM 10000 5 #include "Graph.hpp" 6 class Graphm:public Graph{ 7 private: 8 int numVertex,numEdge; 9 int **matrix; 10 int *mark; 11 VertexType vexs[MAX_VERTEX_NUM]; 12 public: 13 Graphm(); 14 Graphm(int n); 15 int n(); 16 int e(); 17 int first(int ); 18 int next(int,int); 19 void putVex(int v,VertexType value); 20 int locateVex(VertexType u); 21 VertexType getVex(int v); 22 void setEdge(int v1,int v2,int value); 23 void deleteEdge(int ,int ); 24 void setMark(int v,int value); 25 int getMark(int v); 26 int getEdge(int ,int); 27 }; 28 #endif
实现:Graphm.cpp
1 #define VertexType int 2 #include "Graphm.hpp" 3 #include <iostream> 4 Graphm::Graphm(){} 5 Graphm::Graphm(int n){ 6 numVertex=n; 7 numEdge=0; 8 matrix=new int*[numVertex]; 9 for(int i=0;i<numVertex;i++){ 10 matrix[i]=new int[numVertex]; 11 } 12 for(int i=0;i<numVertex;i++) 13 for(int j=0;j<numVertex;j++) 14 matrix[i][j]=0; 15 mark=new int[numVertex]; 16 for(int i=0;i<numVertex;i++)mark[i]=0; 17 } 18 int Graphm::n(){ 19 return numVertex; 20 } 21 int Graphm::e(){ 22 return numEdge; 23 } 24 int Graphm::first(int v1){ 25 int i; 26 for( i=0;i<numVertex;i++){ 27 if(matrix[v1][i]!=0) 28 return i; 29 } 30 return i; 31 } 32 int Graphm::next(int v1,int v2){ 33 int i; 34 for(i=v2+1;i<numVertex;i++){ 35 if(matrix[v1][i]!=0)return i; 36 } 37 return i; 38 } 39 void Graphm::putVex(int v,VertexType value){ 40 vexs[v]=value; 41 } 42 int Graphm::locateVex(VertexType u){ 43 for(int i=0;i<numVertex;i++){ 44 if(u==vexs[i])return i; 45 } 46 return -1; 47 } 48 VertexType Graphm::getVex(int v){ 49 return vexs[v]; 50 } 51 void Graphm::setEdge(int v1,int v2,int value){ 52 if(matrix[v1][v2]==0)numEdge++; 53 matrix[v1][v2]=value; 54 } 55 void Graphm::deleteEdge(int v1,int v2){ 56 if(matrix[v1][v2]==0)numEdge--; 57 matrix[v1][v2]=0; 58 } 59 void Graphm::setMark(int v,int value){ 60 mark[v]=value; 61 } 62 int Graphm::getMark(int v){ 63 if(v>=numVertex)return -1; 64 return mark[v]; 65 } 66 int Graphm::getEdge(int v1,int v2){ 67 return matrix[v1][v2]; 68 }
demo程序:main.cpp
1 #include"Graphm.cpp" 2 #include"Graphm.hpp" 3 #include <iostream> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <stack> 7 #include <queue> 8 using namespace std; 9 int V,E; 10 //深度优先搜索递归版 11 void DFS1(Graphm *g,int v1){ 12 printf("%d ",v1+1); 13 g->setMark(v1,1); 14 for(int w=g->first(v1);w<g->n();w=g->next(v1,w)){ 15 if(g->getMark(w)==0)DFS1(g,w); 16 } 17 } 18 //深度优先搜索非递归版 19 void DFS2(Graphm *g,int v1){ 20 stack<int> s; 21 s.push(v1); 22 g->setMark(v1,1); 23 while(s.empty()!=1){ 24 int temp=s.top(); 25 cout<<temp+1<<" "; 26 s.pop(); 27 for(int i=g->n()-1;i>=0;i--){ 28 if(g->getMark(i)==0&&g->getEdge(temp,i)!=0){ 29 s.push(i); 30 g->setMark(i,1); 31 } 32 } 33 } 34 } 35 //广度优先搜索 36 void BFS(Graphm *g,int v1){ 37 queue<int>q; 38 q.push(v1); 39 g->setMark(v1,1); 40 cout<<v1+1<<" "; 41 while(q.empty()!=1){ 42 int temp=q.front(); 43 q.pop(); 44 for(int i=0;i<g->n();i++){ 45 if(g->getMark(i)==0&&g->getEdge(temp,i)!=0){ 46 q.push(i); 47 g->setMark(i,1); 48 cout<<i+1<<" "; 49 } 50 } 51 } 52 } 53 void print(Graphm &g){ 54 for(int i=0;i<g.n();i++){ 55 for(int j=0;j<g.n();j++){ 56 cout<<g.getEdge(i,j)<<" "; 57 } 58 cout<<endl; 59 } 60 cout<<endl; 61 } 62 int main(){ 63 scanf("%d%d",&V,&E); 64 Graphm G(V); 65 // cout<<G.n()<<" "<<G.e()<<endl; 66 while(E--){ 67 int v1,v2; 68 scanf("%d%d",&v1,&v2); 69 G.setEdge(v1-1,v2-1,1); 70 // cout<<G.e()<<endl; 71 } 72 print(G); 73 for(int i=0;i<G.n();i++){ 74 if(G.getMark(i)==0) 75 DFS1(&G,i); 76 cout<<endl; 77 DFS2(&G,i); 78 cout<<endl; 79 BFS(&G,i); 80 cout<<endl; 81 } 82 return 0; 83 }