关闭

图的邻接表存储表示 图的深度优先遍历和图的广度优先遍历

标签: 图的邻接表存储表示图的广度优先遍历图的深度优先遍历
3460人阅读 评论(0) 收藏 举报
分类:
#include<stdio.h>
#include<stdlib.h>

#define MAX_VERTAX_SIZE 20
#define OK 1
#define ERROR 0

typedef int Status;
typedef char ElemType;

typedef struct EageNode{
	int adjacentVertax;
	struct EageNode* nextAdjacentVertax;
}EageNode, *EageNodePtr;

typedef struct VertaxNode{
	ElemType data;
	EageNodePtr firstEage;
}VertaxNode;

typedef struct GraphAL{
	VertaxNode VertaxArray[MAX_VERTAX_SIZE];
	int vertaxNum;
	int eageNum;
}GraphAL;

//定义队列结构,用于图的广度优先遍历
typedef struct QueueNode{
	ElemType data;
	struct QueueNode* next;
}QueueNode, *QueueNodePtr;
typedef struct Queue{
	QueueNodePtr front;
	QueueNodePtr rear;
}Queue;
Status InitQueue(Queue* Q){
	Q->front = (QueueNodePtr)malloc(sizeof(struct QueueNode));
	if( !Q->front )
		return ERROR;
	Q->rear = Q->front;
	Q->rear->next = NULL;
	return OK;
}
Status EnterQueue(Queue *q, ElemType value){
	QueueNode* n;
	n = (QueueNode*)malloc(sizeof(struct QueueNode));
	if( !n )
		return ERROR;
	n->data = value;
	n->next = q->rear->next;
	q->rear->next = n;
	q->rear = n;
	return OK;
}
Status DeleteQueue(Queue* q,ElemType* value){
	if( q->front == q->rear )
		return ERROR;
	QueueNode* p;
	p = q->front->next;
	*value = p->data;
	q->front->next = p->next;
	free(p);
	if( p == q->rear )
		q->rear = q->front;
	return OK;
}
int IsQueueEmpty(Queue q){
	return q.front == q.rear ? OK : ERROR;
}
/*
int main(){
	Queue q;
	ElemType c;
	InitQueue(&q);
	EnterQueue(&q,'a');
	EnterQueue(&q,'f');
	EnterQueue(&q,'g');
	EnterQueue(&q,'e');
	DeleteQueue(&q,&c);
	printf("%c \n", c);
	printf("&&&&%d", IsQueueEmpty(q));
	DeleteQueue(&q,&c);
	printf("%c \n", c);
	return 0;
}
*/

//返回顶点v在G中的下标
int LocateVertax(GraphAL G, ElemType v){
	int i;
	for( i = 0; i < G.vertaxNum; i++ ){
		if( G.VertaxArray[i].data == v )
			return i;
	}
	return -1;
}
//通过下标得到元素的值
ElemType GetValueFromIndex(GraphAL G, int index){
	return G.VertaxArray[index].data;
}
//创建邻接表无向图
Status CreateUDG_AdjacencyList(GraphAL* G){
	int i;
	ElemType v,w;
	int index_v, index_w;
	EageNodePtr vPtr,wPtr;
	printf("	Create Undigraph\n");
	printf("Please enter the number of Vertax and Eage: ");
	scanf("%d %d%*c", &(G->vertaxNum), &(G->eageNum));

	printf("ok, please input the value of %d Vertax\n", G->vertaxNum);
	for( i = 0; i < G->vertaxNum; i++ ){
		scanf("%c%*c", &(G->VertaxArray[i].data));
		G->VertaxArray[i].firstEage = NULL;
	}

	for( i = 0; i < G->eageNum; i++ ){
		printf("ok, please input the two Vertax of Eage %d (Sepearted by Space) :", i+1);
		scanf("%c %c%*c", &v,&w);	//一条边的两个顶点v w
		index_v = LocateVertax(*G, v);
		index_w = LocateVertax(*G, w);
		wPtr = (EageNode*)malloc(sizeof(EageNode));
		if( !wPtr )
			return ERROR;
		wPtr->adjacentVertax = index_w;
		wPtr->nextAdjacentVertax = G->VertaxArray[index_v].firstEage;
		G->VertaxArray[index_v].firstEage = wPtr;

		vPtr = (EageNode*)malloc(sizeof(EageNode));
		if( !vPtr )
			return ERROR;
		vPtr->adjacentVertax = index_v;
		vPtr->nextAdjacentVertax = G->VertaxArray[index_w].firstEage;
		G->VertaxArray[index_w].firstEage = vPtr;
	}
	return OK;
}
//在图G中找v的第一个邻接顶点,找到则返回该顶点在邻接表中的位置,若没有则返回-1
int FirstAdjacentVertax(GraphAL G, ElemType v){
	int index_v;
	index_v = LocateVertax(G, v);
	if( G.VertaxArray[index_v].firstEage == NULL )
		return -1;
	else
		return (G.VertaxArray[index_v].firstEage)->adjacentVertax;
}
//在图G中找v的从w开始的下一个相邻的顶点
int NextAdjacentVertax(GraphAL G, ElemType v, ElemType w ){
	int index_v,index_w;
	EageNodePtr p;
	index_v = LocateVertax(G, v);
	index_w = LocateVertax(G, w);
	if( G.VertaxArray[index_v].firstEage == NULL )
		return -1;
	p = G.VertaxArray[index_v].firstEage; 		//p pointer to first node
	while( p->nextAdjacentVertax != NULL ){
		if( p->adjacentVertax == index_w )
			return p->nextAdjacentVertax->adjacentVertax;
		p = p->nextAdjacentVertax;
	}
	return -1;
}

//DFS深度优先遍历图:使用递归算法,算法思想:
//		1:从v顶点开始,visit(v),将其设置为已遍历
//		2: 获得v的第一个邻接顶点w,若其存在并且没有访问过,递归遍历;
//		3: 获得v的从w之后的邻接点,若其存在并且没有访问过,递归遍历;直到所有都访问过
int visitedArray[MAX_VERTAX_SIZE];
void visit(ElemType c){
	printf("%c ", c);
}
Status DFS(GraphAL G, ElemType v){
	ElemType w;
	visit(v);
	visitedArray[LocateVertax(G, v)] = 1;
	for( w = GetValueFromIndex(G, FirstAdjacentVertax(G, v)); LocateVertax(G, w) != -1; w = GetValueFromIndex(G, NextAdjacentVertax(G, v, w))){
		if( visitedArray[LocateVertax(G, w)] != 1 )
			DFS(G, w);
	}
	return OK;
}
Status DFSTraverse(GraphAL G){
	int i;
	for( i = 0; i < G.vertaxNum; i++ )
		visitedArray[i] = 0;
	for( i = 0; i < G.vertaxNum; i++ )
		if( visitedArray[i] != 1 )
			DFS(G, GetValueFromIndex(G, i));
	return OK;
}


//BFS(Breadth First Search)
Status BFS(GraphAL G){
	int i,j;
	Queue q;
	ElemType c;
	InitQueue(&q);
	for(i = 0; i < G.vertaxNum; i++)
		visitedArray[i] = 0;
	for(i = 0; i < G.vertaxNum; i++){	//这个for实际执行的次数是连通分量的个数
		if( visitedArray[i] == 0 ){
			EnterQueue(&q, G.VertaxArray[i].data);
			visitedArray[i] = 1;
			while( IsQueueEmpty(q) != OK ){
				DeleteQueue(&q, &c);
				visit(c);
				for( j = FirstAdjacentVertax(G, c); j != -1; j = NextAdjacentVertax(G, c, GetValueFromIndex(G, j))){
					if( visitedArray[j] == 0 ){
						EnterQueue(&q, GetValueFromIndex(G, j));
						visitedArray[j] = 1;
					}
				}
			}
		}
	}
}


//打印无向图的邻接表
void PrintUDG_AdjacentList(GraphAL G){
	int i;
	EageNodePtr p;
	printf("  Adjacency List \n");
	for( i = 0; i < G.vertaxNum; i++ ){
		printf(" %d %c ",i, G.VertaxArray[i]);
		p = G.VertaxArray[i].firstEage;
		while( p != NULL ){
			printf("-->%d", p->adjacentVertax);
			p = p->nextAdjacentVertax;
		}
		printf("\n");
	}
}
int main(){
	GraphAL G;
	CreateUDG_AdjacencyList(&G);
	PrintUDG_AdjacentList(G);

	printf("   DFS(Depth First Search) of UDG(Undigraph)\n");
	DFSTraverse(G);

	printf("\n  BFS(Breadth First Search) of UDG(Undigraph)\n");
	BFS(G);
	return 0;
}

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:70326次
    • 积分:1435
    • 等级:
    • 排名:千里之外
    • 原创:75篇
    • 转载:0篇
    • 译文:0篇
    • 评论:47条
    最新评论