邻接矩阵的表示法

Python017

邻接矩阵的表示法,第1张

在图的邻接矩阵表示法中:

① 用邻接矩阵表示顶点间的相邻关系

② 用一个顺序表来存储顶点信息

图的矩阵

设G=(V,E)是具有n个顶点的图,则G的邻接矩阵是具有如下性质的n阶方阵:

【例】

下图中无向图G 5 和有向图G 6 的邻接矩阵分别为A l 和A 2 。

网络矩阵

若G是网络,则邻接矩阵可定义为:

其中:

w ij 表示边上的权值

∞表示一个计算机允许的、大于所有边上权值的数。

【例】下面带权图的两种邻接矩阵分别为A 3 和A 4 。

图的邻接矩阵存储结构形式说明

#define MaxVertexNum l00 //最大顶点数,应由用户定义

typedef char VertexType//顶点类型应由用户定义

typedef int EdgeType//边上的权值类型应由用户定义

typedef struct{

VextexType vexs[MaxVertexNum] //顶点表

EdeType edges[MaxVertexNum][MaxVertexNum]//邻接矩阵,可看作边表

int n,e//图中当前的顶点数和边数

}MGragh

注意:

① 在简单应用中,可直接用二维数组作为图的邻接矩阵(顶点表及顶点数等均可省略)。

② 当邻接矩阵中的元素仅表示相应的边是否存在时,EdgeTyPe可定义为值为0和1的枚举类型。

③无向图的邻接矩阵是对称矩阵,对规模特大的邻接矩阵可压缩存储。

④邻接矩阵表示法的空间复杂度S(n)=0(n 2 )。

⑤建立无向网络的算法。

void CreateMGraph(MGraph *G)

{//建立无向网的邻接矩阵表示

int i,j,k,w

scanf("%d%d",&G->n,&G->e)//输入顶点数和边数

for(i = 0i <ni++) //读入顶点信息,建立顶点表

{

G->vexs=getchar()

}

for(i = 0i <G->ni++)

{

for(j = 0j <G->nj++)

{

G->edges[i][j] = 0//邻接矩阵初始化

}

}

for(k = 0k <G->ek++)

{//读入e条边,建立邻接矩阵

scanf("%d%d%d",&i,&j,&w)//输入边(v i ,v j )上的权w

G->edges[i][j]=w

G->edges[j][i]=w

}

}//CreateMGraph

该算法的执行时间是0(n+n 2 +e)。由于e

根据图的定义可知,图的逻辑结构分为两部分:V和E的集合。因此,用一个一维数组存放图中所有顶点数据;用一个二维数组存放顶点间关系(边或弧)的数据,称这个二维数组为邻接矩阵。邻接矩阵又分为有向图邻接矩阵和无向图邻接矩阵。

Matlab表达N=4//图中的节点数目

dag=zeros(N,N)//邻接矩阵初始化,值均为0

C=1S=2R=3

W=4//制定各节点编号

dag(C,[RS])=1//有两条有向边:C->R,C->S

dag(R,W)=1//有向边:R->W

dag(S,W)=1//有向边:S->W

/*******************************************

图的遍历演示

以邻接多重表为存储结构,实现连通无向图的深度优先和广度优先遍历.

以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和相应生成树的边集.

*******************************************/

#include<iostream>

# include <string.h>

# include <malloc.h>

# include <conio.h>

using namespace std

int visited[30]

# define MAX_VERTEX_NUM 30

# define OK 1

//typedef int VertexType

typedef int InfoType

typedef struct ArcNode //弧

{

int adjvex

struct ArcNode *nextarc

}ArcNode

typedef struct VNode//表头

{

int data

ArcNode *firstarc

}VNode,AdjList[MAX_VERTEX_NUM]

typedef struct//图

{

AdjList vertices

int vexnum,arcnum

int kind

}ALGraph

void CreateDG(ALGraph &G)

{

int k,i,v1

cout<<endl<<"请输入结点个数: "

cin>>G.vexnum

cout<<"请输入弧的个数: "

cin>>G.arcnum

for(i=1i<=G.vexnumi++)//初使化表头

{

G.vertices[i].data=i

G.vertices[i].firstarc=NULL

}

for(k=1k<=G.vexnumk++) //输入边

{

int v2

cout<<"请输入与结点"<<k<<"相邻的边数:"

cin>>v2

cout<<"请输入与第"<<k<<"个结点相连的结点编号: "

cin>>v1

ArcNode *p

p=(ArcNode*)malloc(sizeof(ArcNode))

if(!p) exit(-1)

p->adjvex=v1

p->nextarc=NULL

G.vertices[k].firstarc=p

for(int i=1i<v2i++)

{

int m

cout<<"请输入与第"<<k<<"个结点相连的结点编号: "

cin>>m

ArcNode *q

q=(ArcNode *)malloc(sizeof(ArcNode))//动态指针

if(!q) exit(-1)

q->adjvex=m //顶点给P

q->nextarc=NULL

p->nextarc=q

p=q

//free(q)

}

//free(p)

}

}

void DFS (ALGraph G,int v )//深度搜索

{

visited[v]=1

cout<<G.vertices[v].data<<" "

ArcNode *x

x=(ArcNode*)malloc(sizeof(ArcNode))

if(!x) exit(-1)

x=G.vertices[v].firstarc

int w

for (xx=x->nextarc)

{ w=x->adjvex

if(visited[w]==0)

DFS(G,w)

}

}

void DFSB (ALGraph G,int v)//深度搜索的边集

{

visited[v]=1

ArcNode *y

y=(ArcNode*)malloc(sizeof(ArcNode))

if(!y) exit(-1)

y=G.vertices[v].firstarc

int u=G.vertices[v].data

int w

for(yy=y->nextarc)

{ w=y->adjvex

if(visited[w]==0)

{

cout<<u<<"--->"<<w<<endl

DFSB(G,w)

}

}

}

typedef struct QNode

{

int data

QNode *next

}QNode,*QueuePtr

typedef struct

{

QueuePtr front

QueuePtr rear

}LinkQueue

void InitQueue (LinkQueue &Q)//建立一个空队列

{

Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode))

if(!Q.front) exit(-1)

Q.front->next=NULL

}

void EnQueue (LinkQueue &Q,int e)//进队

{

QNode *p

p=(QNode*)malloc(sizeof(QNode))

if(!p) exit(-1)

p->data=e

p->next=NULL

Q.rear->next=p

Q.rear=p

//free(p)

}

int DeQueue (LinkQueue &Q,int &e)//出队

{

if(Q.front==Q.rear)

return -1

QNode *p

p=(QNode*)malloc(sizeof(QNode))

if(!p) exit(-1)

p=Q.front->next

e=p->data

Q.front->next=p->next

if(Q.rear==p)

Q.rear=Q.front

free(p)

return e

}

int QueueEmpty (LinkQueue Q)//判断队列是否为空

{

if(Q.front==Q.rear)

return 1

return 0

}

void BFS(ALGraph G,int v)//广度搜索

{

int u

LinkQueue Q

InitQueue(Q)

if(visited[v]==0)

{

visited[v]=1

cout<<G.vertices[v].data<<" "

EnQueue(Q,v)

while(QueueEmpty(Q)!=1)

{

DeQueue(Q,u)

ArcNode *z

z=(ArcNode*)malloc(sizeof(ArcNode))

if(!z) exit(-1)

z=G.vertices[u].firstarc

/*

for(int w=z->adjvexw>=0w=z->nextarc->adjvex)

{

if(visited[w]==0)

{

visited[w]=1

cout<<w<<" "

EnQueue(Q,w)

}

}*/

int w

for(zz=z->nextarc)

{ w=z->adjvex

if(visited[w]==0)

{

visited[w]=1

cout<<w<<" "

EnQueue(Q,w)

}

}

}

}

}

void BFSB (ALGraph G,int v)//广度搜索的边集

{

int u

LinkQueue Q

InitQueue(Q)

if(visited[v]==0)

{

visited[v]=1

EnQueue(Q,v)

while(QueueEmpty(Q)!=1)

{

DeQueue(Q,u)

ArcNode *r

r=(ArcNode*)malloc(sizeof(ArcNode))

if(!r) exit(-1)

r=G.vertices[u].firstarc

int w

for(r!=NULLr=r->nextarc)

{ w=r->adjvex

if(visited[w]==0)

{

visited[w]=1

cout<<u<<"--->"<<w<<endl

EnQueue(Q,w)

}

}

}

}

}

int main()

{

int i

ALGraph G

CreateDG(G)

int x

cout<<"请输入结点数:"

cin>>x

cout<<"邻接表为:"<<endl

for(int j=1j<=xj++)

{

cout<<G.vertices[j].data<<" "

ArcNode *p

p=(ArcNode*)malloc(sizeof(ArcNode))

if(!p) exit(-1)

p=G.vertices[j].firstarc

while(p)

{

cout<<p->adjvex<<" "

p=p->nextarc

}

cout<<endl

}

cout<<"请输入第一个要访问的结点序号:"<<endl

int n

cin>>n

for( i=0i<30i++)

visited[i]=0

cout<<"广度搜索:"<<endl

BFS(G,n)

for( i=0i<30i++)

visited[i]=0

cout<<endl

cout<<"边集:"<<endl

BFSB(G,n)

for( i=0i<30i++)

visited[i]=0

cout<<"深度搜索:"<<endl

DFS(G,n)

for( i=0i<30i++)

visited[i]=0

cout<<endl

cout<<"边集:"<<endl

DFSB(G,n)

//system("pause")

return 0

}

前几天上机刚好做了这个,个人感觉很完美,尽管老师说用的是邻接表而不是多重表,太简单,但还不错,界面输入过程比较繁琐,要严格按照提示来输入,是无向图,等级太低,没办法把执行结果粘出来,应该能看懂吧

#include"stdio.h"

#include"stdlib.h"

#define MaxVertexNum 50 //定义最大顶点数

typedef struct node{ //边表结点

int adjvex//邻接点域

struct node *next//链域

}EdgeNode

typedef struct vnode{ //顶点表结点

char vertex//顶点域

EdgeNode *firstedge//边表头指针

}VertexNode

typedef VertexNode AdjList[MaxVertexNum]//AdjList是邻接表类型

typedef struct {

AdjList adjlist//邻接表

int n,e//图中当前顶点数和边数

} ALGraph//图类型

//=========建立图的邻接表=======

void CreatALGraph(ALGraph *G)

{

int i,j,k

char a

EdgeNode *s//定义边表结点

printf("Input VertexNum(n) and EdgesNum(e): ")

scanf("%d,%d",&G->n,&G->e)//读入顶点数和边数

fflush(stdin)//清空内存缓冲

printf("Input Vertex string:")

for(i=0i<G->ni++) //建立边表

{

scanf("%c",&a)

G->adjlist[i].vertex=a//读入顶点信息

G->adjlist[i].firstedge=NULL//边表置为空表

}

printf("Input edges,Creat Adjacency List\n")

for(k=0k<G->ek++) { //建立边表

scanf("%d%d",&i,&j)//读入边(Vi,Vj)的顶点对序号

s=(EdgeNode *)malloc(sizeof(EdgeNode))//生成边表结点

s->adjvex=j//邻接点序号为j

s->next=G->adjlist[i].firstedge

G->adjlist[i].firstedge=s//将新结点*S插入顶点Vi的边表头部

s=(EdgeNode *)malloc(sizeof(EdgeNode))

s->adjvex=i//邻接点序号为i

s->next=G->adjlist[j].firstedge

G->adjlist[j].firstedge=s//将新结点*S插入顶点Vj的边表头部

}

}

//=========定义标志向量,为全局变量=======

typedef enum{FALSE,TRUE} Boolean

Boolean visited[MaxVertexNum]

//========DFS:深度优先遍历的递归算法======

void DFSM(ALGraph *G,int i)

{//以Vi为出发点对邻接链表表示的图G进行DFS搜索

EdgeNode *p

printf("%c",G->adjlist[i].vertex)//访问顶点Vi

visited[i]=TRUE//标记Vi已访问

p=G->adjlist[i].firstedge//取Vi边表的头指针

while(p) { //依次搜索Vi的邻接点Vj,这里j=p->adjvex

if(! visited[p->adjvex]) //若Vj尚未被访问

DFSM(G,p->adjvex)//则以Vj为出发点向纵深搜索

p=p->next//找Vi的下一个邻接点

}

}

void DFS(ALGraph *G)

{

int i

for(i=0i<G->ni++)

visited[i]=FALSE//标志向量初始化

for(i=0i<G->ni++)

if(!visited[i]) //Vi未访问过

DFSM(G,i)//以Vi为源点开始DFS搜索

} //==========BFS:广度优先遍历=========

void BFS(ALGraph *G,int k)

{ //以Vk为源点对用邻接链表表示的图G进行广度优先搜索

int i,f=0,r=0EdgeNode *p

int cq[MaxVertexNum]//定义FIFO队列

for(i=0i<G->ni++)

visited[i]=FALSE//标志向量初始化

for(i=0i<=G->ni++)

cq[i]=-1//初始化标志向量

printf("%c",G->adjlist[k].vertex)//访问源点Vk

visited[k]=TRUE

cq[r]=k//Vk已访问,将其入队。注意,实际上是将其序号入队

while(cq[f]!=-1) { // 队列非空则执行

i=cq[f]f=f+1//Vi出队

p=G->adjlist[i].firstedge//取Vi的边表头指针

while(p) { //依次搜索Vi的邻接点Vj(令p->adjvex=j)

if(!visited[p->adjvex]) { //若Vj未访问过

printf("%c",G->adjlist[p->adjvex].vertex)//访问Vj

visited[p->adjvex]=TRUE

r=r+1cq[r]=p->adjvex//访问过的Vj入队

}

p=p->next//找Vi的下一个邻接点

}

}//endwhile

}

//==========主函数===========

void main()

{

//int i

ALGraph *G

G=(ALGraph *)malloc(sizeof(ALGraph))

CreatALGraph(G)

printf("Print Graph DFS: ")

DFS(G)

printf("\n")

printf("Print Graph BFS: ")

BFS(G,3)

printf("\n")

}