您的位置:首页 > 其它

图的深度优先搜索和广度优先搜索

2014-12-17 14:52 225 查看
此图是以图的邻接表法作为储存方式,对图进行深度优先搜索和广度优先搜索(均是非递归)

# 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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: