/*
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;
}