图的深度优先和广度优先搜索算法
图的深度优先搜索算法的基本思想是:从图G的某个顶点V0出发,访问V0,然后选择一个与V0相邻且未被访问过的顶点Vi访问,再从Vi出发选择一个与Vi相邻且未被访问的顶点Vj进行访问,依此下去,直到当前被访问过的顶点的所有邻接顶点都已被访问,则按相反顺序退回到已访问的顶点序列中,如果其中的顶点还存在未被访问的相邻顶点W,则从W出发,按相同的方法继续访问。直到图中的所有顶点均被访问。
无向图的深度优先搜索过程示意图:
其程序如下:
#include
#include
#include
#define MaxVertexNum 100
int visited[MaxVertexNum];
typedef struct node
{
int adjvex;
struct node *nextrarc;
int info;
}EdgeNode;
typedef struct vnode
{
char vexdate;
EdgeNode *firstarc;
}VertexNode;
typedef VertexNode AdjList[MaxVertexNum];
typedef struct
{
AdjList adjlist;
int n,e;
}ALGraph;
int initGraph(ALGraph* aGraph);
int mFind(char aChar, ALGraph* aGraph);
int createHead(char aChar, ALGraph* aGraph);
void addBody(char aChar, int aPos, ALGraph* aGraph);
void showGraph(ALGraph* aGraph);
void DFSTraverse(ALGraph* aGraph);
void DFS(ALGraph* aGraph, int v);
int main(void)
{
char a;
char sep1;
char sep2;
int isBody=0;
int isFinish=0;
int headPos=-1;
ALGraph g_graph;
initGraph(&g_graph);
printf("Input arcs like this ' a-> b c d',end with $\n");
while(isFinish==0)
{
isBody=0;
while(1)
{
//a=getChar();
scanf("%c",&a);
if(a=='-'||a=='\n'||a==' '||a=='>')
{
if(a=='>')
isBody=1;
continue;
}
if(a=='$'||a=='#')
{
if(a=='#')
isFinish=1;
break;
}
if(a=='>')
{
isBody=1;
continue;
}
if(isBody==1)
{
addBody(a,headPos,&g_graph);
}
else
{
if((headPos=mFind(a,&g_graph))==-1)
headPos=createHead(a,&g_graph);
}
}
}
showGraph(&g_graph);
printf("The DFS is:\n");
DFSTraverse(&g_graph);
return 0;
}
void DFSTraverse(ALGraph* aGraph)
{
int i=0;
for(i=0; in; i++)
{
visited[i]=0;
}
for(i=0; in; i++)
{
if(!visited[i])
DFS(aGraph,i);
}
}
void DFS(ALGraph* aGraph, int v)
{
EdgeNode* w;
visited[v]=1;
printf(" %c", aGraph->adjlist[v].vexdate);
w=aGraph->adjlist[v].firstarc;
for(w=aGraph->adjlist[v].firstarc; w; w=w->nextrarc)
{
if(!visited[w->adjvex])
DFS(aGraph, w->adjvex);
}
}
void showGraph(ALGraph* aGraph)
{
int i=0;
for(i=0; in; i++)
{
EdgeNode* pos;
printf("%c->", aGraph->adjlist[i]);
pos=aGraph->adjlist[i].firstarc;
while(pos!=NULL)
{
printf("%d",pos->adjvex);
pos=pos->nextrarc;
}
printf("\n");
}
}
void addBody(char aChar, int aPos, ALGraph* aGraph)
{
int inversePos;
EdgeNode* node=(EdgeNode*) malloc(sizeof(EdgeNode));
if((node->adjvex=mFind(aChar,aGraph))==-1)
node->adjvex=createHead(aChar,aGraph);
node->info=-1;
node->nextrarc=NULL;
if(aGraph->adjlist[aPos].firstarc==NULL)
{
aGraph->adjlist[aPos].firstarc=node;
}
else
{
EdgeNode* tail=aGraph->adjlist[aPos].firstarc;
while(tail->nextrarc!=NULL)
tail=tail->nextrarc;
tail->nextrarc=node;
}
inversePos=node->adjvex;
node=(EdgeNode*)malloc(sizeof(EdgeNode));
node->adjvex=aPos;
node->info=-1;
node->nextrarc=NULL;
if(aGraph->adjlist[inversePos].firstarc==NULL)
{
aGraph->adjlist[inversePos].firstarc=node;
}
else
{
EdgeNode* tail=aGraph->adjlist[inversePos].firstarc;
while(tail->nextrarc!=NULL)
tail=tail->nextrarc;
tail->nextrarc=node;
}
}
int createHead(char aChar, ALGraph* aGraph)
{
int currPos=aGraph->n;
aGraph->adjlist[currPos].vexdate=aChar;
aGraph->n++;
return currPos;
}
int mFind(char aChar, ALGraph* aGraph)
{
int i=0;
for(i=0; in; i++)
{
if(aChar==aGraph->adjlist[i].vexdate)
return i;
}
return -1;
}
int initGraph(ALGraph* aGraph)
{
int i=0;
aGraph->e=0;
aGraph->n=0;
for(i=0; iadjlist[i].firstarc=NULL;
}
return 0;
}
在VC2010 C++控制台程序下的运行结果如下截图:
#include
#include
#include
#define MaxVertexNum 100
//队列的声明
typedef struct Qnode
{
int data;
struct Qnode* next;
struct Qnode* prev;
}Qnode;
typedef struct queue
{
Qnode* first;
Qnode* tail;
}Queue;
int isQueueEmpty(Queue* pQue)
{
if(pQue->first==pQue->tail)
return 1;
else
return 0;
}
Queue* queueInit(Queue* pQue)
{
pQue->first=(Qnode*)malloc(sizeof(Queue));
pQue->first->data=-1;
pQue->tail=pQue->first;
return pQue;
}
Qnode* queuePull(Queue* pQue)
{
pQue->tail=pQue->tail->prev;
return pQue->tail->next;
}
void queuePush(Queue* pQue, Qnode* pNode)
{
pNode->next=pQue->first;
pQue->first->prev=pNode;
pQue->first=pNode;
}
Queue* queueEmpty(Queue* pQue)
{
while(pQue->first!=pQue->tail)
{
Qnode* pCurr=pQue->first;
pQue->first=pQue->first->next;
free(pQue->first);
}
return pQue;
}
int visited[MaxVertexNum];
//图的声明
typedef struct node
{
int adjvex;
struct node *nextrarc;
int info;
}EdgeNode;
typedef struct vnode
{
char vexdate;
EdgeNode *firstarc;
}VertexNode;
typedef VertexNode AdjList[MaxVertexNum];
typedef struct
{
AdjList adjlist;
int n,e;
}ALGraph;
int initGraph(ALGraph* aGraph);
int mFind(char aChar, ALGraph* aGraph);
int createHead(char aChar, ALGraph* aGraph);
void addBody(char aChar, int aPos, ALGraph* aGraph);
void showGraph(ALGraph* aGraph);
void BFSTraverse(ALGraph* aGraph);
void BFS(ALGraph* aGraph, int i, Queue* pQue, int* visited);
int main(void)
{
char a;
//char sep1;
//char sep2;
int isBody=0;
int isFinish=0;
int headPos=-1;
ALGraph g_graph;
initGraph(&g_graph);
printf("Input arcs like this 'a->b c d',end with $\n");
while(isFinish==0)
{
isBody=0;
while(1)
{
a=getchar();
//scanf("%c",&a);
if(a=='-'||a=='\n'||a==' '||a=='>')
{
if(a=='>')
isBody=1;
continue;
}
if(a=='$'||a=='#')
{
if(a=='#')
isFinish=1;
break;
}
if(a=='>')
{
isBody=1;
continue;
}
if(isBody==1)
{
addBody(a,headPos,&g_graph);
}
else
{
if((headPos=mFind(a,&g_graph))==-1)
headPos=createHead(a,&g_graph);
}
}
}
showGraph(&g_graph);
printf("The BFS is:\n");
BFSTraverse(&g_graph);
return 0;
}
void BFS(ALGraph* aGraph, int i, Queue* pQue, int* visited)
{
Qnode* temNode=(Qnode*)malloc(sizeof(Qnode));
temNode->data=i;
queuePush(pQue,temNode);
while(isQueueEmpty(pQue)==0)
{
Qnode* currNode=queuePull(pQue);
if(visited[currNode->data]==0)
{
EdgeNode* temarc;
printf("%c",aGraph->adjlist[currNode->data].vexdate);
visited[currNode->data]=1;
temarc=aGraph->adjlist[currNode->data].firstarc;
while(temarc!=NULL)
{
Qnode* insertNode=(Qnode*)malloc(sizeof(Qnode));
insertNode->data=temarc->adjvex; //此处指针未初始化,导致错误
if(visited[insertNode->data]==0)
queuePush(pQue,insertNode);
temarc=temarc->nextrarc;
}
}
}
}
void BFSTraverse(ALGraph* aGraph)
{
Queue gQueue;
int i=0;
for(i=0; in; i++)
{
visited[i]=0;
}
queueInit(&gQueue);
for(i=0; in; i++)
{
if(visited[i]==0)
BFS(aGraph, i, &gQueue, visited);
}
printf("\n");
}
void showGraph(ALGraph* aGraph)
{
int i=0;
for(i=0; in; i++)
{
EdgeNode* pos;
printf("%c->", aGraph->adjlist[i]);
pos=aGraph->adjlist[i].firstarc;
while(pos!=NULL)
{
printf(" %c", pos->adjvex);
pos=pos->nextrarc;
}
printf("\n");
}
}
void addBody(char aChar, int aPos, ALGraph* aGraph)
{
int inversePos;
EdgeNode* node=(EdgeNode*)malloc(sizeof(EdgeNode));
if((node->adjvex=mFind(aChar,aGraph))==-1)
node->adjvex=createHead(aChar, aGraph);
node->info=-1;
node->nextrarc=NULL;
if(aGraph->adjlist[aPos].firstarc==NULL)
aGraph->adjlist[aPos].firstarc=node;
else
{
EdgeNode* tail=aGraph->adjlist[aPos].firstarc;
while(tail->nextrarc!=NULL)
tail=tail->nextrarc;
tail->nextrarc=node;
}
inversePos=node->adjvex;
node=(EdgeNode*)malloc(sizeof(EdgeNode));
node->adjvex=aPos;
node->info=-1;
node->nextrarc=NULL;
if(aGraph->adjlist[inversePos].firstarc==NULL)
aGraph->adjlist[inversePos].firstarc=node;
else
{
EdgeNode* tail=aGraph->adjlist[inversePos].firstarc;
while(tail->nextrarc!=NULL)
tail=tail->nextrarc;
tail->nextrarc=node;
}
}
int createHead(char aChar, ALGraph* aGraph)
{
int currPos=aGraph->n;
aGraph->adjlist[currPos].vexdate=aChar;
aGraph->n++;
return currPos;
}
int mFind(char aChar, ALGraph* aGraph)
{
int i=0;
for(i=0; in; i++)
{
if(aChar==aGraph->adjlist[i].vexdate)
return i;
}
return -1;
}
int initGraph(ALGraph* aGraph)
{
int i=0;
aGraph->e=0;
aGraph->n=0;
for(i=0; iadjlist[i].firstarc=NULL;
}
return 0;
}
另外一方面cc对应着int 3调试中断,堆栈中的存放的局部数据一般情况下是只读的,当发生意外执行堆栈里面的数据就会引发该调试中断。可以认为0x0cc就是有特殊含义的占位符,对于指针而言,它跟NULL是一个意思。
其它具有特殊意义的占位符还有:
0x00000000 - 一般是NULL, 也就是0, 空指针
0xcdcdcdcd- Created but not initialized(创建但未初始化,当字符串看就是 “屯屯屯屯……”)
0xdddddddd- Deleted(删除)
0xfeeefeee- Freed memory set by NT's heap manager(堆管理器释放的内存区域。注:发现有值为0xfeeefeee的指针,就说明对应的内存已被释放掉了)
0xcccccccc - Uninitialized locals in VC6 when you compile w/ /GZ (当编译时没有初始化的局部变量,即野指针,当作字符串看就是“烫烫烫烫……”)
0xabababab - Memory following a block allocated by LocalAlloc() (局部变量内存块)