图可以用邻接表和邻接矩阵表示
一.邻接矩阵:
1.邻接矩阵的生成(无向图):
数据结构:
<pre name="code" class="cpp">typedef struct
{
char v[maxNum];//图的顶点信息
int e[maxNum][maxNum];//图的顶点信息
int vNum;//顶点个数
int eNum;//边的个数
}graph;
2.邻接矩阵的生成
void createGraph(graph *g)//创建图g
{
cout<<"正在创建无向图..."<<endl;
cout<<"请输入顶点个数vNum:";
cin>>g->vNum;
cout<<"请输入边的个数eNum:";
cin>>g->eNum;
int i,j;
//初始画图g
for(i=1;i<=g->vNum;i++)
for(j=1;j<=g->vNum;j++)
g->e[i][j]=0;
//输入边的情况
cout<<"请输入边的头和尾"<<endl;
for(int k=1;k<=g->eNum;k++)
{
cin>>i>>j;
g->e[i][j]=1;
g->e[j][i]=1;
}
}
3.邻接矩阵的深度优先(递归):
void dfs(graph *g,int i)
{
//cout<<"顶点"<<g->v[i]<<"已经被访问"<<endl;
cout<<"顶点"<<i<<"已经被访问"<<endl;
visited[i]=1;//标记顶点i被访问
for(int j=0;j<g->vNum;j++)
{
if(g->e[i][j]!=0&&visited[j]==0)
dfs(g,j);
}
}
void DFS(graph *g)
{
int i;
//初始化visited数组,表示一开始所有顶点都未被访问过
for(i=0;i<g->vNum;i++)
visited[i]=0;
//深度优先搜索
for(i=0;i<g->vNum;i++)
if(visited[i]==0)//如果这个顶点为被访问过,则从i顶点出发进行深度优先遍历
dfs(g,i);
}
3.1 深度优先遍历的非递归算法伪代码
</pre>4.邻接矩阵的广度优先(要用到队列):<p></p><p></p><pre name="code" class="cpp">void BFS(graph *g);//广度优先遍历图g
void bfs(graph *g,int i)
{
int k,j;
cout<<"顶点"<<i<<"已经被访问"<<endl;
visited[i]=1;//标记顶点i被访问
q.push(i);
while(!q.empty())
{
k=q.front();
q.pop();
//cout<<q.size();
for(j=1;j<=g->vNum;j++)
{
if(g->e[k][j]!=0&&visited[j]==0)
{
cout<<"顶点"<<j<<"已经被访问"<<endl;
visited[j]=1;
q.push(j);
}
}
}
}
二.邻接表
1.邻接表的数据结构:“
typedef struct node //边表结点
{
int adjvex; //邻接点域
struct node *next; //域链
//若是要表示边上的权,则应增加一个数据域
}EdgeNode;
typedef struct vnode //顶点边结点
{
VertexType vertex; //顶点域
EdgeNode *firstedge;//边表头指针
}VertexNode;
typedef VertexNode AdjList[MaxVertexNum]; //AdjList是邻接表类型
typedef struct
{
AdjList adjlist; //邻接表
int n, e; //图中当前顶点数和边数
}ALGraph;
2.邻接表的生成
void CreateGraphAL(ALGraph *G)
{
int i, j, k;
EdgeNode * s;
printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");
scanf("%d,%d", &(G->n), &(G->e)); // 读入顶点数和边数
printf("请输入顶点信息(输入格式为:顶点号<CR>)每个顶点以回车作为结束:\n");
for (i = 0; i < G->n; i++) // 立有n个顶点的顶点表
{
scanf("\n%c", &(G->adjlist[i].vertex)); // 读入顶点信息
G->adjlist[i].firstedge = NULL; // 点的边表头指针设为空
}
printf("请输入边的信息(输入格式为:i,j):\n");
for (k = 0; k < G->e; k++) // 建立边表
{
scanf("\n%d,%d", &i, &j); // 读入边<Vi,Vj>的顶点对应序号
s = new EdgeNode; // 生成新边表结点s
s->adjvex = j; // 邻接点序号为j
s->next = G->adjlist[i].firstedge; // 将新边表结点s插入到顶点Vi的边表头部
G->adjlist[i].firstedge = s;
s = new EdgeNode;
s->adjvex = i;
s->next = G->adjlist[j].firstedge;
G->adjlist[j].firstedge = s;
}
}
3.邻接表的深度优先
void DFS(ALGraph *G, int i)
{
//以vi为出发点对邻接表表示的图G进行深度优先搜索
EdgeNode *p;
printf("visit vertex:%c\n", 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]) //若vi尚未被访问
DFS(G, p->adjvex); //则以Vj为出发点向纵深搜索
p = p->next; //找vi的下一邻接点
}
}
void DFSTraverseM(ALGraph *G)
{
int i;
for (i = 0; i < G->n; i++)
visited[i] = FALSE;
for (i = 0; i < G->n; i++)
if (!visited[i])
DFS(G, i);
}
4.邻接表的广度优先
typedef struct
{
int front;
int rear;
int count;
int data[QueueSize];
}CirQueue;
void InitQueue(CirQueue *Q)
{
Q->front = Q->rear = 0;
Q->count = 0;
}
int QueueEmpty(CirQueue *Q)
{
return Q->count == 0;
}
int QueueFull(CirQueue *Q)
{
return Q->count == QueueSize;
}
void EnQueue(CirQueue *Q, int x)
{
if (QueueFull(Q))
printf("Queue overflow");
else
{
Q->count++;
Q->data[Q->rear] = x;
Q->rear = (Q->rear + 1) % QueueSize;
}
}
int DeQueue(CirQueue *Q)
{
int temp;
if (QueueEmpty(Q))
{
printf("Queue underflow");
return NULL;
}
else
{
temp = Q->data[Q->front];
Q->count--;
Q->front = (Q->front + 1) % QueueSize;
return temp;
}
}
void BFS(ALGraph*G, int k)
{ // 以vk为源点对用邻接表表示的图G进行广度优先搜索
int i;
CirQueue Q; //须将队列定义中DataType改为int
EdgeNode *p;
InitQueue(&Q); //队列初始化
printf("visit vertex:%c\n", G->adjlist[k].vertex); //访问源点vk
visited[k] = TRUE;
EnQueue(&Q, k); //vk已访问,将其人队。(实际上是将其序号人队)
while (!QueueEmpty(&Q))
{ //队非空则执行
i = DeQueue(&Q); //相当于vi出队
p = G->adjlist[i].firstedge; //取vi的边表头指针
while (p)
{ //依次搜索vi的邻接点vj(令p->adjvex=j)
if (!visited[p->adjvex])
{ //若vj未访问过
printf("visit vertex:%c\n", G->adjlist[p->adjvex].vertex); //访问vj
visited[p->adjvex] = TRUE;
EnQueue(&Q, p->adjvex); //访问过的vj人队
}
p = p->next; //找vi的下一邻接点
}
}
}
void BFSTraverseM(ALGraph *G)
{
int i;
for (i = 0; i < G->n; i++)
visited[i] = FALSE;
for (i = 0; i < G->n; i++)
if (!visited[i])
BFS(G, i);
}