1 / 27

第7章 图

第7章 图. 7.2 图的存储结构. 7.2.1 邻接矩阵 int a[n][n]. 1.无向图的邻接矩阵 1 如果 ( v i , v j ) ∈ E A(i,j)= 0 其它. 2.有向图的邻接矩阵 1 如果 < v i , v j > ∈ E A(i,j)= 0 其它. 7.2.1 邻接矩阵.

varana
Download Presentation

第7章 图

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第7章 图 7.2 图的存储结构

  2. 7.2.1 邻接矩阵int a[n][n] • 1.无向图的邻接矩阵 • 1 如果(vi,vj)∈E • A(i,j)= • 0 其它 • 2.有向图的邻接矩阵 • 1 如果<vi,vj>∈E • A(i,j)= • 0 其它

  3. 7.2.1 邻接矩阵 A1= A2=

  4. 邻接矩阵的特点 • (1) A(i,i)=0 1≤i≤n; • (2) 无向图的邻接矩阵是对称的 • A(i,j)=A(j,i) 1≤i≤n, 1≤j≤n; • 存入上(下)三角形,需n(n+1)/2个单元; • (3) 无向图的邻接矩阵的第i行(或第i列)非零元素的 • 个数正好是第i个顶点的度TD(vi ); • (4) 有向图的邻接矩阵一般不对称。 • 有向图需要n2个单元; • (5) 有向图的邻接矩阵的 • 第i行非零元素的个数是第i个顶点的出度OD(vi); • 第j列非零元素的个数是第j个顶点的入度ID(vi);

  5. 7.2.1 邻接矩阵int a[n][n] • 3. 网(带权值的图)的邻接矩阵 • wij i!=j 且 (vi,vj)∈E或<vi,vj>∈E • A(i,j)= ∽ i!=j ,无边或弧 • 0 i==j , 对角线元素

  6. 2 5 20 40 70 1 4 80 30 50 3 6 3. 网(带权值的图)的邻接矩阵 • 0 20 30 ∞∞∞ • 20 0∞ 40 ∞∞ • 30 ∞0 50 ∞∞ • ∞ 40 50 0 70 80 • ∞∞∞ 70 0∞ • ∞∞∞ 80 ∞0

  7. 7.2.2 邻接矩阵表示的图类 const int MaxVertices=10; const int MaxWeight=32767; class AdjMWGraph { private: int Vertices[10]; //顶点信息的数组 int Edge[MaxVertices][MaxVertices]; //边的权值信息的矩阵 int numE; //当前的边数 int numV; //当前的顶点数 public: ………; //公有函数 private: ………; //私有函数 }

  8. class AdjMWGraph { private:…….;// 数据成员 public: AdjMWGraph(); //构造函数 void CreatG(int n,int e); //建立一个图的邻接矩阵 void PrintOut(); //输出图的邻接矩阵 void Depth(); //对连通图深度优先遍历的调用 void DepthF(); //对非连通图深度优先遍历 void Broad(); //对连通图广度优先遍历的调用 void BroadF(); //对非连通图深度优先遍历 private: void Depth(int v, int visited[]); void Broad(int v,int visited[]); };

  9. class AdjMWGraph { private: ………; // 数据成员 public: ………..; //公有函数 private: //对连通图的深度优先遍历,visit为访问标记 void Depth(int v, int visited[]); //对连通图的广度优先遍历,visit为访问标记 void Broad(int v,int visited[]); };

  10. //(1)构造函数 AdjMWGraph::AdjMWGraph() { for( int i=0; i i<MaxVertices; i++ ) Vertices[i]=0; for ( int i=0; i<MaxVertices; i++ ) for ( int j=0; j<MaxVertices; j++ ) { if( i==j ) Edge[i][j]=0; else Edge[i][j]=MaxWeight; //MaxWeight表示无穷 } numE=0; //当前边个数初始为0 numV=0; //当前顶点个数初始为0 }

  11. //(2)建立一个图的邻接矩阵 void AdjMWGraph::CreatG(int n,int e) {int i,vi,vj,w; //w为边的权值 numE=e; numV=n; cout<<endl<<" 输入顶点的信息(整型):" ; for ( i=0; i<numV; i++ ) { cout<<"\n "<<i+1<<": "; cin>>Vertices[i]; } for ( i=0; i<numE; i++ ) { cout<<endl<<" 输入边的信息(vi,vj,w):"; cin>>vi>>vj>>w; Edge[vi-1][vj-1]=w; Edge[vj-1][vi-1]=w; //对于无向图 } }

  12. //(3)输出图的邻接矩阵 void AdjMWGraph::PrintOut() { int i; cout<<"\n 输出顶点的信息(整型): "<<endl; for ( i=0; i<numV; i++ ) cout<<Vertices[i]<<" "; cout<<endl<<"\n 输出邻接矩阵:" ; for ( i=0; i<numV; i++ ) { cout<<endl<<i+1<<": "; for ( int j=0; j<numV ;j++ ) cout<<Edge[i][j]<<" "; cout<<endl; } }

  13. 在主函数中应用 //声明创建一个对象G0 //调用建立函数,4个顶点5条边 //输出邻接矩阵的信息 • int main() • { AdjMWGraphG0; • G0.CreatG(4,5); • G0.PrintOut(); • _getch(); • return 0; • }

  14. data adj 7.2.3 邻接链表 • 1. 顶点的结构 • const int MaxVertices=100; • typedef int VerT; //顶点数据类型 • typedef int DistT; //边的数据类型 • struct item { VerT data; //顶点数据 • Edge *adj; //邻接边的指针 • }; • 2.数组(向量) • item Vertices[MaxVertices]; //顶点的数组 Item 顶点结构

  15. dest weight next 7.2.3 邻接链表 • 3. 边的结构 • struct Edge • { int dest; //邻接顶点下标 • DistT weight; //边的权值,或更多 • Edge *next; //指针 • }; Edge 边结构

  16. 7.2.3 邻接链表 • const int MaxVertices=100; • typedef int VerT; • typedef int DistT; • struct item { VerT data; //顶点数据 • Edge *adj; //邻接边的指针 • }; • item Vertices[MaxVertices]; //顶点的数组

  17. 7.2.4 邻接链表的图类 const int MaxVertices=10; class AdjTWGraph //邻接表图类定义 { private: item Vertices[MaxVertices]; //顶点信息数组,表头向量 int numV; //顶点数组的当前元素个数 int numE; //当前边的条数 public: AdjTWGraph(); //构造函数 ~AdjTWGraph(); //析构函数 ……….; private://私有函数 }

  18. const int MaxVertices=10; class AdjTWGraph //邻接表图类定义 {private: ……..;// public: AdjTWGraph(); //构造函数 ~AdjTWGraph(); //析构函数 void CreatG(int n,int e); //输入建立邻接表 void PrintOut(); //输出数据信息 void DepthFirst(); //调用深度优先遍历 void BroadFirst(); //调用广度优先遍历 Private: //私有函数 …………………..; }

  19. class AdjTWGraph //邻接表图类定义 {private: ……..;// public: void DepthFirst() ; //调用深度优先遍历 void BroadFirst(); //调用广度优先遍历 private: //对连通图深度优先遍历,visit为访问标记 void DepthFirst(int v, int visited[]); //对连通图广度优先遍历,visit为访问标记 void BroadFirst(int v, int visited[]); };

  20. //(1)构造函数 AdjTWGraph::AdjTWGraph() { for ( int i=0; i<MaxVertices; i++ ) { Vertices[i].data=0; Vertices[i].adj=NULL; } numV=0; numE=0; } Vertices[i] 0 1 0 ^ 1 0 ^ 2 0 ^ 0 ^ 3

  21. (2)析构函数 AdjTWGraph::~AdjTWGraph(void) { for ( int i=1; i<=numV; i++ ) { Edge *p=Vertices[i].adj,*q; while ( p!=NULL) { q=p->next; delete p; p=q; } Vertices[i].adj=NULL; } } p q 1 1 1 3 2 4 ∧ 2 2 1 3 ∧ 3 3 1 2 4 ∧ 4 4 1 3 ∧

  22. //(3)建立一个图的邻接链表 void AdjTWGraph::CreatG(int n,int e) { int vi,vj; DistT w; numE=e; numV=n; cout<<"\n 输入顶点的信息(整型):" ; for (int i=1; i<=numV; i++ ) { cout<<"\n "<<i<<": "; cin>>Vertices[i].data; } for ( int i=1; i<=numE; i++ ) { cout<<"\n 输入边的信息(顶点号vi 顶点号vj 边的权值W):"; cin>>vi>>vj>>w;

  23. //---------------------- 在第vi条链表上,链入边(vi,vj)的结点 Edge *q=new Edge; q->dest=vj; q->weight=w; q->next=NULL; //vj是vi的邻接顶点,w是权值 if(Vertices[vi].adj==NULL) Vertices[vi].adj=q; //第一次插入 else //非第一次插入 {Edge *curr=Vertices[vi].adj, *pre=NULL; while (curr!=NULL && curr->dest<vj ) { pre=curr; curr=curr->next; } if ( pre==NULL ) //在第一个结点前插入 { q->next=Vertices[vi].adj; Vertices[vi].adj=q; } else {q->next=pre->next; //在其他位置插入 pre->next=q; } }

  24. //-------------------在第vj条链表上,链入边(vj,vi)的结点//-------------------在第vj条链表上,链入边(vj,vi)的结点 Edge *p=new Edge; p->dest=vi; p->weight=w; p->next=NULL; if(Vertices[vj].adj==NULL) Vertices[vj].adj=p; //第一次插入 else //非第一次插入 {Edge *curr=Vertices[vj].adj,*pre=NULL; while (curr!=NULL && curr->dest<vi ) { pre=curr; curr=curr->next; } if ( pre==NULL ) //在第一个结点前插入 { p->next=Vertices[vj].adj; Vertices[vj].adj=p; } else { p->next=pre->next; //在其他位置插入 pre->next=p; } } } //for } //函数结束

  25. //(4)输出图的邻接表信息函数 void AdjTWGraph::PrintOut() { Edge *pre,*curr; for ( int i=1; i<=numV; i++ ) { cout<<"\n 输出顶点编号信息、邻接点编号和边权值:"; cout<<setw(3)<<i<<setw(6)"<<Vertices[i].data; curr=Vertices[i].adj; while ( curr!=NULL ) {cout<<" v"<<curr->dest<<" w"<<curr->weight; curr=curr->next; } cout<<endl; }//for }// PrintOut()

  26. 在主函数中应用 //声明创建一个对象G0 //调用建立函数n0个顶点e0条边 //输出邻接矩阵的信息 • int main() • { AdjTWGraphG0; • int n0,e0; • cin>>n0>>e0; • G0.CreatG(n0,e0); • G0.PrintOut(); • _getch(); • return 0; • }

More Related