基于相邻矩阵实现图的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 }

 

 

 

       

posted @ 2018-12-15 13:55  记得每天写代码  阅读(984)  评论(0编辑  收藏  举报