无向图邻接链表的广度优先搜索

个人认为图的算法看起来非常简洁,但是实现起来需要基础很扎实。因为经常会涉及多种简单的数据结构,怎样把他们恰当的串联起来,不会报那种,空指针了,类型不匹配,实体类型不符合了等等。
在做无向图邻接链表广度优先搜索的时候,写的很冒火,想去找别的博主的代码借鉴一下,发现大部分,真的是大部分,都是有问题的,有些甚至都运行不出来。于是硬着头皮自己写了。
第一步是分析:
无向图里面用到的数据结构一个是链表,这里用到了两次。一个链表用于存放每个元素的与之相连的元素,用了一个邻接链表。还要考虑所有元素怎么连成一张图,前面的链表可以得到的散开的这种形式x1------x2,要把所有元素集合起来就能变成一张图,我又用了一个链表给他所有元素存起来。那么大的链表里面就有所有元素,以及每个元素的相连元素。也就是说访问这个链表就能得到这张图的结构。
还用到了一个队列,主要是需要用到先进先出的性质,为了使数据的相互联系更加紧密,在声明队列结构体的时候,我用到的是链表的指针。
剩下的就是从一个源节点开始不断的入队出队了,这个思想并不复杂。

要注意的就是指针了,怎么处理空的情况,在写链表的时候要特别注意,这是这个代码最重要的部分,其他的都是在调用他,如果写出问题了后面的访问肯定是有问题的。
(下面代码是根据算法导论来写 的,要是没看过的书的话可能不知道白色灰色黑色等是在干嘛…其实就是在标明一种状态,简单说一下就是初始化都是白色,访问到他了(也就是让他入队列了),他就变成灰色,当把它的相连的子结点都访问完了(也就是他出队列了),就标记成黑色)

#include "stdafx.h"
#include <stdio.h>
#include<stdlib.h>
#define N 5    //the total number of points
#define MAX 0x3f3f3f3f

typedef enum Color { W, G, B }Corlor;    //white gray black
typedef struct point_ *point;
typedef struct link_ *link;
typedef struct link_ {
	link rear;   //尾指针
	point node;   //数据域
	link next;   //指针域
	link front;  //头指针
}l;

typedef struct point_      //define points' property
{
	int key;
	int distance;
	Color c;
	link Adj;  //other points connected to the point
	point parent;    //parent is a precessor
	point next;  //this is for queue
}p;

typedef struct queue_  //队列
{
	link head;
	link tail;
}*queue, q;

link INI_LINK(link L)
{
	L = (link)malloc(sizeof(l));
	L->rear = NULL;
	L->node = NULL;
	L->next = NULL;
	L->front = NULL;
	return L;
}

link INSERT_LINK(link L, point dot) 
{
	link new_p = (link)malloc(sizeof(l));
	new_p=INI_LINK(new_p);
	new_p->node = dot;
	new_p->next = NULL;
	if (L->front == NULL)
	{
		L->front = L->rear = new_p;
	}
	else
	{
		L->rear->next = new_p;
		L->rear = new_p;
		if (L->front->next == NULL)
			L->front->next = L->rear;
	}
	return L;
}

queue INI_QUEUE(queue que)
{
	que = (queue)malloc(sizeof(q));
	que->head = NULL;
	que->tail = NULL;
	return que;
}
void ENQUEUE(queue que, point x)
{
	link new_p = (link)malloc(sizeof(l));
	new_p = INI_LINK(new_p);
	new_p->node = x;
	new_p->next = NULL;
	if (que->head == NULL)
	{
	    que->head = que->tail = new_p;
	}
	else
	{
	    que->tail->next = new_p;
		que->tail = new_p;
		if (que->head->next == NULL)
			que->head->next = que->tail;
	}

}
void DEQUEUE(queue que)
{
	if (que->head == NULL)
	{
		return;
	}
	if (que->head == que->tail)
	{
		que->head = que->head->next = NULL;
		que->tail = que->tail->next = NULL;
	}
	else
	{
		que->head = que->head->next;
	}
}
//////////////////////////////////////////以上是构造基本的数据结构  链表和队列,为图的操作打下基础


point INI_POINT(int k)         //初始化结点
{
	point m = (point)malloc(sizeof(p));
	link x = (link)malloc(sizeof(l));
	x->node = NULL;
	x->front = NULL;
	x->rear = NULL;
	x->next = NULL;
	m->Adj = x;
	m->parent = NULL;
	m->c = W;
	m->key = k;
	m->distance = MAX;
	m->next = NULL;
	return m;
}

point INI_SOURCE_POINT(point source)
{
	source->c = G;
	source->distance = 0;
	return source;
}
/////////////////以上是初始化结点

void CONNECTION(point x1, point x2)         //连接两个结点
{
	x1->Adj = INSERT_LINK(x1->Adj, x2);
	x2->Adj = INSERT_LINK(x2->Adj, x1);
}

void BFS(link All_Point, point s)
{
	queue Q=(queue)malloc(sizeof(q));
	Q=INI_QUEUE(Q);
	ENQUEUE(Q, s);
	while (Q->tail != NULL)
	{
		link u = Q->head;
		printf("(%d, %d)     ", u->node->key, u->node->distance);
		DEQUEUE(Q);
		while (u->node->Adj->front != NULL)
		{
			link v = u->node->Adj->front;
			if (v->node->c == W)
			{
				v->node->c = G;
				v->node->distance = u->node->distance + 1;
				v->node->parent = u->node;
//				printf("v= %d, v parent shi =%d  v distance is %d\n", v->node->key, v->node->parent->key, v->node->distance);
				ENQUEUE(Q, v->node);
			}
			u->node->Adj->front = u->node->Adj->front->next;
		}
		u->node->c = B;
	}
}

int main()
{
	link All_Point=(link)malloc(sizeof(l));   //这个链表里面存着所有的结点
	point p1, p2, p3, p4, p5;
	All_Point=INI_LINK(All_Point);
	p1 = INI_POINT(12);       
	p2 = INI_POINT(18);
	p3 = INI_POINT(22);
	p4 = INI_POINT(31);
	p5 = INI_POINT(44);
	p1 = INI_SOURCE_POINT(p1);     //p1 is a source point
	CONNECTION(p1, p2);
	CONNECTION(p1, p3);
	CONNECTION(p3, p4);
	CONNECTION(p3, p5);
	INSERT_LINK(All_Point, p1);
	INSERT_LINK(All_Point, p2);
	INSERT_LINK(All_Point, p3);
	INSERT_LINK(All_Point, p4);
	INSERT_LINK(All_Point, p5);
	printf("the result is:\n");
	BFS(All_Point, p1);
	return 0;
}

在这里插入图片描述
我连接的是这样一个图,结果显示的是结点和对应的距离

          18--------------------12(源节点)
                                |
                                |
                                |
                                |
                                22  -----------------31
                                |
                                |
                                |
                                44

猜你喜欢

转载自blog.csdn.net/alike_meng/article/details/83714583