1. 程式人生 > >基於相鄰矩陣實現圖的ADT

基於相鄰矩陣實現圖的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 }