此图是以图的邻接表法作为储存方式,对图进行深度优先搜索和广度优先搜索(均是非递归)
# include <stdio.h>
# include <stdlib.h>
# define True 1
# define False 0
# define Error -1
# define OK 1
# define MAX_VERTEX_NUM 20
int visited[MAX_VERTEX_NUM];
typedef char VertexData;
typedef enum{DG,DN,UDG,UDN} GraphKind;
typedef struct ArcNode{ //弧节点结构
int adjvex;
struct ArcNode *nextarc;
// OtherInfo info;
}ArcNode;
typedef struct VertexNode{ //表头节点结构
VertexData data;
ArcNode *firstarc;
}VertexNode;
typedef struct {
VertexNode vertex[MAX_VERTEX_NUM];
int vexnum,arcnum;
GraphKind kind;
}AdjList;
//**********************关于栈的知识*******************************
typedef struct node
{
int num;
struct node *next;
}LinkStackNode, *LinkStack;
int InitStack(LinkStack *S) //初始化栈
{
(*S) = (LinkStack)malloc(sizeof(LinkStackNode));
(*S)->next = NULL;
if ((*S) != NULL)
return True;
else
return False;
}
int Push(LinkStack S, int x) //进栈
{
LinkStack temp;
temp = (LinkStack)malloc(sizeof(LinkStackNode));
if (temp == NULL)
return False;
temp->num = x;
temp->next = S->next;
S->next = temp;
return True;
}
int Pop(LinkStack S, int *x) //出栈
{
LinkStack temp;
temp = S->next;
if (temp == NULL)
return False;
*x = temp->num;
S->next = temp->next;
free(temp);
return True;
}
int IsEmpty(LinkStack S) //判断栈是否为空
{
if (S->next == NULL)
return True;
else
return False;
}
//*************************************************************************
//****************************关于队的知识**********************************************
typedef struct Node
{
int data;
struct Node *next;
}LinkQueueNode;
typedef struct
{
LinkQueueNode *front;
LinkQueueNode *rear;
}LinkQueue;
int InitQueue(LinkQueue *Q) // 链队列的初始化
{
Q->front = (LinkQueueNode *)malloc(sizeof(LinkQueueNode));
if (Q->front != NULL)
{
Q->rear = Q->front;
Q->front->next = NULL;
return (True);
}
else
return False;
}
int EnterQueue(LinkQueue *Q, int x) //链队列入队
{
LinkQueueNode *NewNode;
NewNode = (LinkQueueNode *)malloc(sizeof(LinkQueueNode));
if (NewNode != NULL)
{
NewNode->data = x;
NewNode->next = NULL;
Q->rear->next = NewNode;
Q->rear = NewNode;
return True;
}
else
return False;
}
int DeleteQueue(LinkQueue *Q, int *x) // 链队列出队
{
LinkQueueNode *p;
if (Q->front == Q->rear)
return False;
p = Q->front->next;
Q->front->next = p->next;
if (Q->rear == p)
Q->rear = Q->front;
*x = p->data;
free(p);
return True;
}
int Empty(LinkQueue *Q) //判断链栈是否为空
{
if (Q->front == Q->rear)
return True;
else
return False;
}
//*************************************************************************************
int FirstAdjVertex(AdjList *g, int v) //求v的第一个邻接点
{
int w;
ArcNode *p;
p = g->vertex[v].firstarc;
if (p == NULL)
return Error;
w = p->adjvex;
return w;
}
int NextAdjVertex(AdjList *g, int v, int w) //求v相对于w的下一个邻接点
{
int k;
ArcNode *p;
p = g->vertex[v].firstarc;
while (p->adjvex != w)
{
p = p->nextarc;
}
p = p->nextarc;
if (p == NULL)
return Error;
else
{
k = p->adjvex;
return k;
}
}
int LocateVertex(AdjList *g, VertexData v) //求顶点位置函数
{
int j = Error,k;
for (k = 0; k < g->vexnum ; k++)
if (g->vertex[k].data == v)
{
j = k;break;
}
return j;
}
void Crtadjlist(AdjList *g) //创建邻接链表
{
int n,e,i,j,k;
char vt,vh;
ArcNode *p;
printf("请输入图的顶点个数和弧的个数\n");
scanf("%d%d", &n, &e);
g->vexnum = n;
g->arcnum = e;
printf("请输入顶点信息\n");
getchar();
for (i = 0; i < n; i++)
{
scanf("%c", &(g->vertex[i].data));
g->vertex[i].firstarc = NULL;
}
printf("请输入弧的两个顶点\n");
for (k = 0; k < e; k++)
{
getchar();
scanf("%c%c",&vt,&vh);
i = LocateVertex(g,vt);
j = LocateVertex(g,vh);
p = (ArcNode *)malloc(sizeof(ArcNode));
p->adjvex = j;
p->nextarc = g->vertex[i].firstarc;
g->vertex[i].firstarc = p;
}
}
void DepthFirstSearch(AdjList *g, int v0) //深度优先搜索
{
LinkStackNode *S;
int v, w;
InitStack(&S);
Push(S, v0);
while ( !IsEmpty(S))
{
Pop(S, &v);
if (!visited[v])
{
printf("%c ",g->vertex[v].data );
visited[v] = True;
w = FirstAdjVertex(g,v);
while (w != -1)
{
if (!visited[w])
Push(S, w);
w = NextAdjVertex(g,v,w);
}
}
}
}
void TraverseGraph(AdjList *g) //深搜
{
int vi;
for (vi = 0; vi < g->vexnum ; vi++)
visited[vi] = False; //初始化标志数组
for (vi = 0; vi < g->vexnum; vi++)
if (!visited[vi])
DepthFirstSearch(g,vi);
}
void BreadthFirstSearch(AdjList *g, int v0) // 广度优先搜索
{
LinkQueue Q;
int v, w;
printf("%c ", g->vertex[v0].data);
visited[v0] = True;
InitQueue(&Q);
EnterQueue(&Q,v0);
while (!Empty(&Q))
{
DeleteQueue(&Q, &v);
w = FirstAdjVertex(g, v);
while (w != -1)
{
if (!visited[w])
{
printf("%c ",g->vertex[w].data);
visited[w] = True;
EnterQueue(&Q,w);
}
w = NextAdjVertex(g,v,w);
}
}
}
void BreadthTraverseGraph(AdjList *g) //广搜
{
int vi;
for (vi = 0; vi < g->vexnum ; vi++)
visited[vi] = False; //初始化标志数组
for (vi = 0; vi < g->vexnum; vi++)
if (!visited[vi])
BreadthFirstSearch(g,vi);
}
int main(void)
{
AdjList g;
Crtadjlist (&g);
printf("深度优先搜索遍历输出\n");
TraverseGraph(&g);
printf("\n广度优先搜索遍历输出\n");
BreadthTraverseGraph(&g);
printf("\n");
return 0;
}
原文地址:http://blog.csdn.net/java_oracle_c/article/details/41981663