数据结构与C语言实现(九)——图(上):邻接表,DFS与BFS

//邻接表

#include <stdio.h>
#include <stdlib.h>
#define	MAXSIZE 100

typedef struct LNode_Vertex* Vertex;
typedef struct LNode_Edge* Edge;
typedef struct LNode_List* List;
typedef struct LNode_Queue* Queue;

struct LNode_Vertex
{
	int vex;
	Edge ptr_edge;
};


struct LNode_Edge
{
	int adjvex;
	int weight;
	Edge next;
};
//因为邻接表的数据结构是,每个顶点表中的节点都引导出一串边节点

struct LNode_Queue
{
	List front;
	List rear;	
};

struct LNode_List
{
	int data;
	List next;
};


LNode_Vertex ver[MAXSIZE];
int num_vertex, num_edge;
int visited[MAXSIZE];
void Create_Graph()
{
	printf("你要输入的点和边数\n");
	
	scanf("%d %d", &num_vertex, &num_edge);
	printf("下面请输入顶点\n");
	for (int i = 0; i < num_vertex; i++)
	{
		scanf("%d", &ver[i].vex);
	}
	printf("下面请输入顶点1,顶点2,权值\n");
	for (int i = 0; i < num_edge; i++)
	{
		int vex1, vex2, w;
		scanf("%d %d %d", &vex1, &vex2, &w);
		Edge E = (Edge)malloc(sizeof(struct LNode_Edge));//建立一个边节点
		if(ver[vex1-1].ptr_edge == NULL)
			ver[vex1-1].ptr_edge = E;
		else
		{
			Edge p = ver[vex1-1].ptr_edge;
			while (p->next != NULL)//直到找到顶点节点所引导的一系列节点的最后
			{
				p = p->next;//每次往后移动一位
			}
			p->next = E;//将最后一个的next指向E
		}
		E->weight = w;
		E->adjvex = vex2;
		E->next = NULL;
	}

}


void Print_Graph()
{
	for (int i = 0; i < num_vertex; i++)
	{
		printf("%d——》", ver[i].vex);
		if (ver[i].ptr_edge != NULL)
		{
			printf("[%d,%d]->", ver[i].ptr_edge->adjvex, ver[i].ptr_edge->weight);
			while (ver[i].ptr_edge->next != NULL)
			{
				printf("[%d,%d]->", ver[i].ptr_edge->next->adjvex, ver[i].ptr_edge->next->weight);
				ver[i].ptr_edge->next = ver[i].ptr_edge->next->next;
			}
		}
		putchar('\n');
	}
}

void DFS(int i)//从第几个顶点开始,1234标号
{
	visited[i] = 1;//被访问过的置1
	printf("%d", ver[i-1].vex);//说明走到过了哪个标号
	for (int j = 1; j <= num_vertex; j++)//在所有的顶点里寻找
		if (!visited[j])//如果上一级的下面还有没有被访问的
			DFS(j);//那就访问之
}

//为了完成BFS,首先我们需要完成一些关于队列的函数,包括入队和出队
Queue CreateQueue()
{
	Queue Q = (Queue)malloc(sizeof(struct LNode_Queue));
	Q->front = Q->rear = NULL;
	return Q;
}

int Is_Empty(Queue Q)
{
	if ((Q->front == NULL) && (Q->rear == NULL))
		return 1;
	else
		return 0;

}

void AddQ(Queue Q,int Item)
{
	List L = (List)malloc(sizeof(struct LNode_List));
	if ((Q->rear == NULL))
	{
		Q->front = L;
		Q->rear = L;
		L->data = Item;
		L->next = NULL;
	}
	else
	{
		Q->rear->next = L;
		Q->rear = L;
		L->data = Item;
		L->next = NULL;
	}
}


int ExitQ(Queue Q)
{
	List q;
	
	if (Q->front == NULL)
	{
		printf("Error:队列中没有元素可以出队");
		return -1;
	}	
	q = Q->front;
	if (Q->front == Q->rear)
	{
		Q->front = NULL;
		Q->rear = NULL;
	}
		
	else
		Q->front = Q->front->next;
	int ans = q->data;
	free(q);
	return ans;
}

void BFS(int i)
{
	for (int j = 0; j < MAXSIZE; j++)
		visited[j] = 0;
	Queue Q = CreateQueue();
	visited[i] = 1;
	AddQ(Q, i);
	printf("%d", ver[i - 1].vex);

	while (!Is_Empty(Q))
	{
		int j = ExitQ(Q);
		//j的所有邻边全部入队
		Edge E = ver[j - 1].ptr_edge;//暂时不去考虑没有邻边的情况
		do
		{
			int k = E->adjvex;
			
			if (!visited[k])
			{
				visited[k] = 1;
				printf("%d", ver[k - 1].vex);
				AddQ(Q, k);
			}
			E = E->next;
		} while (E != NULL);
	}
}
int main()
{
	
	Create_Graph();
	Print_Graph();
	putchar('\n');
	DFS(2);
	putchar('\n');
	BFS(2);
	return 0;
}

/*
4 6 
1 2 3 4
1 4 9
4 3 8 
1 2 5
2 4 6
1 3 7
3 1 2
*/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值