69,380
社区成员
发帖
与我相关
我的任务
分享
/*
图的深度优先遍历
出处:一条鱼@博客园 http://www.cnblogs.com/yanlingyin/
-12-26
*/
#include <stdlib.h>
#include <stdio.h>
struct node /* 图顶点结构定义 */
{
int vertex; /* 顶点数据信息 */
struct node *nextnode; /* 指下一顶点的指标 */
};
typedef struct node *graph; /* 图形的结构新型态 */
struct node head[9]; /* 图形顶点数组 */
int visited[9]; /* 遍历标记数组 */
/********************根据已有的信息建立邻接表********************/
void creategraph(int node[20][2],int num)/*num指的是图的边数*/
{
graph newnode; /*指向新节点的指针定义*/
graph ptr;
int from; /* 边的起点 */
int to; /* 边的终点 */
int i;
for ( i = 0; i < num; i++ ) /* 读取边线信息,插入邻接表*/
{
from = node[i][0]; /* 边线的起点 */
to = node[i][1]; /* 边线的终点 */
/* 建立新顶点 */
newnode = ( graph ) malloc(sizeof(struct node));
newnode->vertex = to; /* 建立顶点内容 */
newnode->nextnode = NULL; /* 设定指标初值 */
ptr = &(head[from]); /* 顶点位置 */
while ( ptr->nextnode != NULL ) /* 遍历至链表尾 */
ptr = ptr->nextnode; /* 下一个顶点 */
ptr->nextnode = newnode; /* 插入节点 */
}
}
/********************** 图的深度优先搜寻法********************/
void dfs(int current)
{
graph ptr;
visited[current] = 1; /* 记录已遍历过 */
printf("vertex[%d]\n",current); /* 输出遍历顶点值 */
ptr = head[current].nextnode; /* 顶点位置 */
while ( ptr != NULL ) /* 遍历至链表尾 */
{
if ( visited[ptr->vertex] == 0 ) /* 如过没遍历过 */
dfs(ptr->vertex); /* 递回遍历呼叫 */
ptr = ptr->nextnode; /* 下一个顶点 */
}
}
/****************************** 主程序******************************/
int main()
{
graph ptr;
int node[20][2] = { {1, 2}, {2, 1}, /* 边线数组 */
{1, 3}, {3, 1},
{1, 4}, {4, 1},
{2, 5}, {5, 2},
{2, 6}, {6, 2},
{3, 7}, {7, 3},
{4, 7}, {4, 4},
{5, 8}, {8, 5},
{6, 7}, {7, 6},
{7, 8}, {8, 7} };
int i;
//clrscr();
for ( i = 1; i <= 8; i++ ) /* 顶点数组初始化 */
{
head[i].vertex = i; /* 设定顶点值 */
head[i].nextnode = NULL; /* 指针为空 */
visited[i] = 0; /* 设定遍历初始标志 */
}
creategraph(node,20); /* 建立邻接表 */
printf("Content of the gragh's ADlist is:\n");
for ( i = 1; i <= 8; i++ )
{
printf("vertex%d ->",head[i].vertex); /* 顶点值 */
ptr = head[i].nextnode; /* 顶点位置 */
while ( ptr != NULL ) /* 遍历至链表尾 */
{
printf(" %d ",ptr->vertex); /* 印出顶点内容 */
ptr = ptr->nextnode; /* 下一个顶点 */
}
printf("\n"); /* 换行 */
}
printf("\nThe end of the dfs are:\n");
dfs(1); /* 打印输出遍历过程 */
printf("\n"); /* 换行 */
puts(" Press any key to quit...");
// getch();
}
//广度优先
#include "stdio.h"
#include "stdlib.h"
typedef char DataType;
#define MaxSize 100
#define MaxVertices 10
#define MaxEdges 100
#define MaxWeight 10000
typedef struct
{
DataType list[MaxSize];
int size;
}SeqList;
typedef struct
{
DataType queue[MaxSize];
int rear;
int front;
int count;
}SeqCQueue;
typedef struct
{
int row;
int col;
int weight;
}RowColWeight;
typedef struct
{
SeqList Vertices;
int edge[MaxVertices][MaxVertices];
int numOfEdges;
}AdjMGraph;
//顺序表初始化
void ListInitiate(SeqList *L)
{
L->size=0;
}
//顺序表插入函数
int ListInsert(SeqList *L,int i,DataType x)
{
int j;
if (L->size>=MaxSize)
{
printf ("顺序表已满无法插入!\n");
return 0;
}
else if (i<0||i>L->size)
{
printf ("参数i不合法!\n");
return 0;
}
else
{
for (j=L->size;j>i;j--)
L->list[j]=L->list[j-1];
L->list[i]=x;
L->size++;
return 1;
}
}
//图G初始化
void Initiate(AdjMGraph *G,int n)
{
int i,j;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
{
if (i==j)
G->edge[i][j]=0;
else
G->edge[i][j]=MaxWeight;
}
G->numOfEdges=0;//边的条数数置为0
ListInitiate(&G->Vertices);//顺序表初始化
}
//在图G中插入结点vertex
void InsertVertex(AdjMGraph *G,DataType vertex)
{
ListInsert(&G->Vertices,G->Vertices.size,vertex);
}
//在图G中插入边
void InsertEdge(AdjMGraph *G,int v1,int v2,int weight)
{
if (v1<0||v2>G->Vertices.size||v2<0||v1>G->Vertices.size)
{
printf ("参数v1或v2越界出错!\n");
exit(1);
}
G->edge[v1][v2]=weight;
G->numOfEdges++;
}
//在图G中寻找序号为v的结点的第一个邻接结点
int GetFirstVex(AdjMGraph G,int v)
{
int col;
if (v<0||v>G.Vertices.size)
{
printf ("参数v1越界出错!\n");
exit(1);
}
for (col=0;col<G.Vertices.size;col++)
if (G.edge[v][col]>0&&G.edge[v][col]<MaxWeight)
return col;
return -1;
}
//在图G中寻找v1结点的邻接结点v2的下一个邻接结点
int GetNextVex(AdjMGraph G,int v1,int v2)
{
int col;
if (v1<0||v1>G.Vertices.size||v2<0||v2>G.Vertices.size)
{
printf ("参数v1或v2越界出错!\n");
exit(1);
}
for (col=v2+1;col<G.Vertices.size;col++)
if (G.edge[v1][col]>0&&G.edge[v1][col]<MaxWeight)
return col;
return -1;
}
//在图G中插入n个结点信息V和e条边信息E(创图函数)
void CreatGraph(AdjMGraph *G,DataType V[],int n,RowColWeight E[],int e)
{
int i,k;
Initiate(G,n);
for (i=0;i<n;i++)
InsertVertex(G,V[i]);
for (k=0;k<e;k++)
InsertEdge(G,E[k].row,E[k].col,E[k].weight);
}
//队列初始化
void QueueInitiate(SeqCQueue *Q)
{
Q->rear=0;
Q->front=0;
Q->count=0;
}
//队列非空
int QueueNotEmpty (SeqCQueue Q)
{
if (Q.count!=0)
return 1;
else
return 0;
}
//入队列
int QueueAppend(SeqCQueue *Q,DataType x)
{
if((Q->rear+1)%MaxSize == Q->front)
{
printf("队列已满!\n");
exit(1);
}
Q->queue[Q->rear] =x;
Q->rear = (Q->rear+1)%MaxSize;
Q->count++;
return 1;
}
//出队列
int QueueDelete(SeqCQueue *Q,DataType *x)
{
if(Q->front == Q->rear)
{
printf("队列是空的!\n");
exit(1);
}
*x = Q->queue[Q->front];
Q->front = (Q->front+1)%MaxSize;
Q->count--;
return 1;
}
//图的广度优先遍历函数
//连通图G以v为初始点访问操作为Visit()的广度优先遍历
//数组visited标记了相应结点是否已访问过,0表示未访问,1表示已访问
void BroadFSearch(AdjMGraph G,int v,int visited[],void Visit(DataType item))
{
DataType u,w;
SeqCQueue queue;
Visit(G.Vertices.list[v]);
visited[v]=1;
QueueInitiate(&queue);
QueueAppend(&queue,v);
while (QueueNotEmpty(queue))
{
QueueDelete(&queue,&u);
w=GetFirstVex(G,u);
while(w!=-1)
{
if (!visited[w])
{
Visit(G.Vertices.list[w]);
visited[w]=-1;
QueueAppend(&queue,w);
}
w=GetNextVex(G,u,w);
}
}
}
//非连通图G访问操作为Visit()的广度优先遍历
void BroadFirstSearch(AdjMGraph G,void Visit(DataType item))
{
int i;
int *visited=(int *)malloc(sizeof(int)*G.Vertices.size);
for (i=0;i<G.Vertices.size;i++)
visited[i]=0;
for(i=0;i<G.Vertices.size;i++)
if (!visited[i])
BroadFSearch(G,i,visited,Visit);
free(visited);
}
//定义访问操作的函数
void Visit(DataType item)
{
printf (" %c ",item);
}
//主函数
void main(void)
{
AdjMGraph g1;
DataType a[]={'1','2','3','4','5'};//图的结点
RowColWeight rcw[]={{0,1,1},{0,2,1},{0,3,1},{0,4,1},{1,0,1},{1,3,1},{2,0,1},{2,4,1},{3,0,1},{3,1,1},{4,0,1},{4,2,1}};
int n=5,e=12;
int i,j;
CreatGraph(&g1,a,n,rcw,e);//创图函数
printf ("结点集合为: \n");
for (i=0;i<g1.Vertices.size;i++)
printf (" %c ",g1.Vertices.list[i]);
printf ("\n");
printf ("\n");
printf ("权值集合为: \n");
for (i=0;i<g1.Vertices.size;i++)
{
for (j=0;j<g1.Vertices.size;j++)
printf ("%5d ",g1.edge[i][j]);
printf ("\n");
}
printf ("\n广度优先搜索序列为:\n");
BroadFirstSearch(g1,Visit);
printf ("\n");
}