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

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

#include<stdio.h>
#include<stdlib.h>

#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;i<g->numvex;i++)
	{
		getchar();
		scanf("%c",&(g->vex[i].c) );
		g->vex[i].first=NULL;
	}
	//建立边集
	printf("输入边两边顶点的下标:\n");
	for(j=0;j<g->edge;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;i<g->numvex;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;i<MAXVEX;i++)
	{
		visited[i]=0;
	}
	for(i=0;i<g->numvex;i++)
	{
		if(!visited[i])
		{
			DFS(g,i,visited);
		}
	}

}

//BFS遍历
void TraBFS(Graph *g)
{
	int i,j;
	LinkQueue q;
	int visited[MAXVEX];
	for(i=0;i<MAXVEX;i++)
	{
		visited[i]=0;
	}
	InitQueue(&q);
	for(i=0;i<g->numvex;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;
}

在这里插入图片描述
一开始出队列写错了,广度遍历不对,找了好久的原因。

  • 52
    点赞
  • 332
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值