图的邻接表创建及深度优先遍历和广度优先遍历

最近在学图,写个笔记。
图的创建一般有邻接矩阵和邻接表两种方法,邻接矩阵对于边数相对于顶点较少的图会有极大的浪费,所以用邻接表,用数组与链表相配合
顶点用一维数组储存
所有顶点的邻接点构成一个线性表,因为邻接点的个数不确定,所以用单链表
图的邻接表创建及深度优先遍历和广度优先遍历_第1张图片
图的深度优先搜索是对先序遍历的推广 一个递归的过程,沿着一个方向遍历,一直到最后,然后再回来到另一个结点沿着一个方向。
广度优先遍历就是一层一层的遍历。如上图
上代码:

#include
#include

#define MAXVEX 7   //代表最大顶点数
#define INFINITY 65535 //代表无穷大

typedef struct GraphNode
{
	int index;    //下标
	struct GraphNode *next;  //指向下一个的指针
}GraphNode;

typedef struct Gra
{
	char c;  //顶点元素
	GraphNode *first ;
}Gra;

typedef struct Graph
{
	Gra vex[MAXVEX];
	int numvex,edge;  //顶点元素和边的数量
}Graph;

//创建一个队列,用来广度优先遍历
typedef struct QNode
{
	int data;
	struct QNode *next;
}QNode,*Queueprt;

typedef struct
{
	Queueprt front,rear;   
}LinkQueue;

//队列的初始化
void InitQueue(LinkQueue *q)
{
	q->front=q->rear=(Queueprt)malloc(sizeof(QNode));
	q->front->next=NULL;
}

//入队列
void EnQueue(LinkQueue *q,int e)
{
	Queueprt p;
	p=(Queueprt)malloc(sizeof(QNode));
	p->data=e;
	q->rear->next=p;
	p->next=NULL;
	q->rear=p;
}

//出队列
void DeQueue(LinkQueue *q,int *e)
{
	if(q->front==q->rear)
	{
		return;
	}
	Queueprt p;
	p=q->front->next;
	*e = p->data;             
	q->front->next=p->next;
	if(p==q->rear)
	{
		q->rear=q->front;
	}
	free(p);
}

//判断队列是否为空
int QueueEmpty(LinkQueue *q)
{
	if(q->front==q->rear)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}
//创建图
void create(Graph *g)
{
	int i,j,m,n;
	GraphNode *p,*q;
	printf("输入顶点元素的数量和边的数量:\n");
	scanf("%d %d",&(g->numvex),&(g->edge));
	printf("输入顶点元素:\n");
	for(i=0;inumvex;i++)
	{
		getchar();
		scanf("%c",&(g->vex[i].c) );
		g->vex[i].first=NULL;
	}
	//建立边集
	printf("输入边两边顶点的下标:\n");
	for(j=0;jedge;j++)
	{
		scanf("%d %d",&m,&n);
		p=(GraphNode *)malloc(sizeof(GraphNode));
		p->index=m;
		p->next=g->vex[n].first;
		g->vex[n].first=p;          //这里是把first移到p


		q=(GraphNode *)malloc(sizeof(GraphNode));
		q->index=n;
		q->next=g->vex[m].first;       
		g->vex[m].first=q;
	}	
}

void print(Graph *g)
{
	int i;
	GraphNode *p;
	for(i=0;inumvex;i++)
	{
		p=g->vex[i].first;
		while(p)
		{
			printf("(%c,%c)",g->vex[i].c,g->vex[p->index].c);
			p=p->next;
		}
		printf("\n");
	}
}

//DFS遍历

void DFS(Graph *g,int i,int *visited)
{
	GraphNode *p;
	visited[i]=1;
	printf("%c ",g->vex[i].c);
	p=g->vex[i].first;
	while( p )
	{
		if(!visited[p->index])
		{
			DFS(g,p->index,visited);
		}
		p=p->next;
	}

}

void TraDFS(Graph *g)
{
	int i;
	int visited[MAXVEX];
	for(i=0;inumvex;i++)
	{
		if(!visited[i])
		{
			DFS(g,i,visited);
		}
	}

}

//BFS遍历
void TraBFS(Graph *g)
{
	int i,j;
	LinkQueue q;
	int visited[MAXVEX];
	for(i=0;inumvex;i++)
	{
		if(!visited[i])
		{
			printf("%c ",g->vex[i].c);
			visited[i]=1;
			EnQueue(&q, i);
			while(!QueueEmpty(&q))
			{
				DeQueue(&q,&i);
				GraphNode *p = g->vex[i].first;
				while( p )
				{
					if(!visited[p->index])
					{
						printf("%c ",g->vex[p->index].c);
						visited[p->index]=1;
						EnQueue(&q,p->index);
					}
					p=p->next;
				}
			}

		}
	}

}

int main(){
	
	Graph g;
	create(&g);
	print(&g);
	printf("DFS遍历结果:\n");
	TraDFS(&g);
	printf("\nBFS遍历结果为:\n");
	TraBFS(&g);
	printf("\n");
	return 0;
}

图的邻接表创建及深度优先遍历和广度优先遍历_第2张图片
一开始出队列写错了,广度遍历不对,找了好久的原因。

你可能感兴趣的:(数据结构与算法)