韩清秀

第六章小结 图结构

图结构这一章真的非常有难度,我其实没有理解太透,作业实践题都没有做出来,所以这一章的博客写写第六章的心得。

G=(V,E)V顶点集合和E边集合构成。

1)一些重要的基本概念:

  1. 权和网:边上的数值为权,带权的图称为网。
  2. 度,入度和出度:顶点v的度是指和v相关联的边的数目。入度是以顶点v为头的弧的数目,出度是以v为尾的弧的数目。
  3. 路径和路径长度:在无向图中,从顶点v到顶点v 的路径是顶点序列。如果是有向图,路径也有向。路径长度是一条路径上经过的边和弧的数目。
  4. 连通,连通图和连通分量:在无向图中,如果从顶点v到顶点v   有路径,则为连通。图中任意两个顶点都是连通的,则为连通图。连通分量,无向图中的极大连通子图。
  5. 强连通图和强连通分量:在有向图中,连通图称为强连通图,连通分量称为强连通分量。
  6. 连通图的生成树:一个极小连通子图,含有图中全部顶点,但只有n-1条边,称为连通图的生成树。

2)非常重要的图的存储结构:

1.邻接矩阵:

#define MaxInt 32767
#define MVNum 100
typedef struct{
char vexs[MVNum];//顶点表
int arcs[MVNum][MVNum];//邻接矩阵
int vexnum,arcnum;//图的当前点数和边数
}AMGraph;

优点:(1)便于判断两点之间是否有边(2)便于计算各顶点的度

缺点:(1)不便于增添和删除顶点操作。(2)不便于统计边的数目(3)空间复杂度为O(n2 ).

 

 

2.邻接表:(链式存储结构)

#define MVNum 100
typedef struct ArcNode//边结点
{
int adjvex;//该边所指向的顶点的位置
struct ArcNode *nextarc;//指向下一条边的指针
int info;//和边相关的信息
}ArcNode;
typedef struct VNode//顶点信息
{
char data;
ArcNode *firstarc;//指向第一条依附该顶点的边的指针
}VNode,AdjList[MVNum];//邻接表
typedef struct
{
AdjList vertices;
int vexnum,arcnum;//图当前的顶点数和边数
}ALGraph;

 

优点:(1)便于增删顶点(2)便于统计边的数目(3)空间效率高

缺点:(1)不变判断是否有边(2)不便计算有向各顶点的度。

3.十字链表

4.邻接多重表

3)关于图的一些重要操作:

1.创建图:

(1)基于邻接矩阵的创建

int CreateUDN(AMGraph &G)
{
int i,j,k,w,v1,v2;
cin>>G.vexnum>>G.arcnum;//输入总顶点数总边数
for( i=0;i<G.vexnum;++i)
cin>>G.vexs[i];
for(int i=0;i<G.vexnum;++i)//初始化邻接矩阵,边值均为最大值
    for( j=0;j<G.vexnum;++j)
         G.arcs[i][j]=MaxInt;
 for( k=0;k<G.arcnum;++k)//构造邻接矩阵
 {
  cin>>v1>>v2>>w;
  i=locatevex(G,v1);//确定v1,v2的位置,数组下标
  j=locatevex(G,v2);
G.arcs[i][j]=w;
G.arcs[j][i]=G.arcs[i][j];
}
 return 1;
}

 

(2)基于邻接表的创建

int CreateUDG(ALGraph &G)
{
int i,j,k,v1,v2;
ArcNode *p1,*p2;
 cin>>G.vexnum>>G.arcnum;
 for(i=0;i<G.vexnum;++i)    //构造表头结点表
 {
cin>>G.vextices[i].data;
 G.vextices[i].firstarc=NULL;//初始化表头结点的指针域为NULL
 }
for(k=0;k<G.arcnum;++k)//构造邻接表
{
cin>>v1>>v2;
i=locatevex(G,v1);
//求v1,v2在G中的位置,下标
j=locatevex(G,v2);
p1= new ArcNode;//生成新的边结点*p1
p1->adjvex=i;
p1->nextarc=G.vertices[i].firstarc;//插入边表头部,头插法
G.vertices[i].firstarc=p1;
p2=new ArcNode;
p2->adjvex=i;
p2->nextarc=G.vertices[j].firstarc;
G.vertices[j].firstarc=p2;
}
return 1;
}

 

2.遍历:

深度优先搜索遍历:类似树的先序遍历

广度优先搜索遍历:类似于树的层次遍历

                                                                      邻接表

                      (1)深度优先遍历(DFS)

                                                                       邻接矩阵

       连通图

                                                                       邻接表

                        (2)广度优先遍历(BFS)

                                                                        邻接矩阵

图    

                                                                       邻接表

                      (1)深度优先遍历(DFS)

                                                                       邻接矩阵

       非连通图

                                                                       邻接表

                        (2)广度优先遍历(BFS)

                                                                        邻接矩阵

辅助数组:visit[vexnum+1]={false};

(4)最小生成树:各边代价之和最小的生成树。

1.普里姆算法(加点法):

 U集合,V-U集合,一个顶点在U中,另一个顶点在V-U中,这两个顶点的边的权值

选择,加入U集合,刷新U,V-U集合。

辅助数组:closedge[MVNum]

初始化:将各边权值都置为无穷大(邻接矩阵)

初态:在U,V-U中的最小权值的边进入刷新

流程:在每一次刷新后,找到与U中顶点邻接的所有邻接点,比较,最小权值边所在的两个顶点的V-U中的顶点进入U中,剩下的顶点保持,等待下一次刷新对比大小

终态:所有V-U中的顶点都进入到U中,U=V.

 2.克鲁斯卡尔算法(加边法):

权值大小排列,从小到大排列,存入数组Edge中,在该数组中找权值最小的边,若该边依附的两个顶点属于同一个连通分量,则选择下一条最小权值边。若不同连通分量,则输出该边。

5)最短路径算法:

迪杰斯特拉:以最短路径长度递增的次序求得各路径。

弗洛伊德:将v 到v 的路径长度初始化,然后进行n次比较和更新

后面的都不太懂了。

所以这一章我觉得 还是比较难的,要好好复习才行。

接下来,我想,还是好好学习书中剩下的内容,第七和第八章,还有还是要提高自己编程的水平,把这章 的编程题好好完成。

 

 

posted on 2019-05-19 20:10  韩清秀  阅读(369)  评论(2编辑  收藏  举报

导航