图算法之bfs/dfs

/*
created:2014.08.21
updated:2014.08.28
auther:yejing
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NO_WEIGHT 0x7fffffff
#define INFINITY 0x7fffffff
int time = 0;//时间戳

typedef struct NODE{
	struct NODE* next;
	int value;
}node_t;


typedef struct QUEUE{
	node_t* front;
	node_t* rear;
}queue_t;

typedef enum{
	WHITE,
	GRAY,
	BLACK
}color_t;

typedef struct GRAPH{
	char* vex_vector;//顶点向量
	int* color;//颜色
	int* parent;//父节点
	int* deepth;//节点被发现时的深度,bfs使用
	int* disc_tm;//节点被发现的时间
	int* fini_tm;//节点被搜索完成的时间
	int arcs[255][255];
	int vexnum, arcnum;
}graph_t;

queue_t* create_queue(void){
	queue_t* tmp = (queue_t*)malloc(sizeof(queue_t));
	if(!tmp)
		tmp->front = tmp->rear = NULL;
		
	tmp->front->value = -1;
	return tmp;
}

void enqueue(queue_t* queue, int value){
	if(!queue)
		return;

	node_t *node = (node_t*)malloc(sizeof(node_t));
	queue->rear->next = node;
	queue->rear = node;

	return;
}

node_t dequeue(queue_t* queue){
	node_t node;
	node.value = -1024;
	if(!queue)
		return node;
	if(queue->front == queue->rear)
		return node;

	node_t* tmp = queue->front;
	queue->front = queue->front->next;

	node.value = tmp->value;
	free(tmp);
	return node;
}

int find(graph_t g, char vex_vector){
	int i = 0;
	for(i; i < g.vexnum; ++i)
		if(g.vex_vector[i] == vex_vector)
			return i;

	return -1;
}

 graph_t create_graph(void){
	int i = 0, j = 0;
	graph_t graph;
	memset((char*)&graph, 0, sizeof(graph));
	
	printf("input the arcnum, less than 255\n");
	scanf("%d", &graph.arcnum);
	getchar();
	printf("input the vexnum, less thar 255\n");
	scanf("%d", &graph.vexnum);
	getchar();
	
	graph.color = (int*)malloc(sizeof(int) * graph.vexnum);
	graph.deepth = (int*)malloc(sizeof(int) * graph.vexnum);
	graph.parent = (int*)malloc(sizeof(int) * graph.vexnum);
	graph.disc_tm = (int*)malloc(sizeof(int) * graph.vexnum);
	graph.fini_tm = (int*)malloc(sizeof(int) * graph.vexnum);
	for(i = 0; i < graph.vexnum; ++i){
		graph.color[i] = WHITE;
		graph.deepth[i] = INFINITY;
		graph.parent[i] = -1;
		graph.disc_tm[i] = 0;
		graph.fini_tm[i] = 0;
	} 

	printf("begin inputing the vex_vector, total num:%d \n", graph.vexnum);
	graph.vex_vector = (char*)malloc(sizeof(char) * graph.vexnum);
	for(i = 0; i < graph.vexnum; ++i){
		printf("vex_vector %d \n", i);
		scanf("%c", &graph.vex_vector[i]);
		getchar();
	}
	printf("vex_vector input finished\n");

	printf("initializing arc weights...\n");
	for(i = 0; i < graph.vexnum; ++i)
		for(j = 0; j < graph.vexnum; ++j)
			graph.arcs[i][j] = NO_WEIGHT;


	int arc_weight;
	int tmp_index1, tmp_index2;
	char vex_vector1, vex_vector2;
	printf("begin inputing the weight of the arc, total num:%d format: vex_vector1 vex_vector2 arc_weight\n", graph.arcnum);
	for(i = 0; i < graph.arcnum; ++i){
		printf("arc %d\n", i);
		scanf("%c %c %d", &vex_vector1, &vex_vector2, &arc_weight);
		getchar();
		tmp_index1 = find(graph, vex_vector1);
		tmp_index2 = find(graph, vex_vector2);

		if(tmp_index2 && tmp_index1)
			graph.arcs[tmp_index1][tmp_index2] = graph.arcs[tmp_index2][tmp_index2] = arc_weight;
		else
			printf("input vex_vectors error, vex_vectors are %c and %c\n", vex_vector1, vex_vector2);
	}
	printf("weight input finished\n");


	return graph;
}
int first_vex_of_graph(graph_t graph, int k)  
{  
    int i;  
    if(k>=0 && k<graph.vexnum)  
        for(i=0;i<graph.vexnum;i++)  
            if(graph.arcs[k][i] != NO_WEIGHT)  
                return i;  
     return -1;  
}  
int next_vex_of_graph(graph_t graph, int i, int j)  
{  
    int k;  
    if(i>=0 && i<graph.vexnum && j>=0 && j<graph.vexnum)  
        for(k=j+1; k<graph.vexnum; k++)  
            if(graph.arcs[i][k] != NO_WEIGHT)  
                return k;  
     return -1;  
}  

void breadth_first_search(graph_t graph, int s){
	int i, j, k;
	queue_t* queue = create_queue();
	if(!queue)
		return;
	
	graph.color[s] = GRAY;
	graph.deepth[s] = 0;
	graph.parent[s] = -1;
	enqueue(queue, s);
	while(queue->front != queue->rear){
		k = dequeue(queue).value;
		for(i = first_vex_of_graph(graph, k); i >= 0; i = next_vex_of_graph(graph, k, i)){
			if(graph.color[i] = WHITE){
				graph.color[i] = GRAY;
				graph.deepth[i] = graph.deepth[k] + graph.arcs[k][i];
				graph.parent[i] = k;
				enqueue(queue, i);
			}
		}
		graph.color[i] = BLACK;
	}
}

void dfs_visit(graph_t* pgraph, int u){
	int i = 0;
	
	pgraph->color[u] = GRAY;
	pgraph->disc_tm[u] = ++time;
	
	for(i = first_vex_of_graph(*pgraph, u); i >= 0; i = next_vex_of_graph(*pgraph, u, i)){
		if(pgraph->color[i] == WHITE){
			pgraph->parent[i] = u;
			dfs_visit(pgraph, i);
		}
	}
	pgraph->color[u] = BLACK;
	pgraph->fini_tm[u] = ++time;
	
	return;
}

void deepth_first_search(graph_t graph)  
{  
	int i = 0;
	for(i = 0; i < graph.vexnum; ++i){
		if(graph.color[i] == WHITE)
			dfs_visit(&graph, i);
	}
	return;
}  

int main(int argc, char* argv[]){
	graph_t graph = create_graph();
	breadth_first_search(graph, 0);
	deepth_first_search(graph);
	return 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值