邻接表c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了邻接表c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)相关的知识,希望对你有一定的参考价值。
graph.c
#include <stdio.h> #include <stdlib.h> #include <limits.h> #include "aqueue.h" #define MAX_NUM 100 typedef char node_type; typedef struct arc_node { int pos; int distance; struct arc_node * next; } Arc_node;//保存Node节点的相邻节点信息 typedef struct node { node_type info; Arc_node * next; } Node;//保存节点信息 typedef struct graph { Node adjlist[MAX_NUM]; int vertexs, brim; } Graph;//邻接表 static Arc_node * make_node(const int pos, const int distance) { Arc_node * new_node = (Arc_node *)malloc( sizeof(Arc_node) ); if ( new_node == NULL ) exit(1); new_node->next = NULL; new_node->distance = distance; new_node->pos = pos; return new_node; } void g_create(Graph * graph) { int num; int i, j, k; char c; Arc_node * tmp; printf("输入节点个数:"); scanf("%d", &graph->vertexs); getchar(); printf("输入顶点信息:"); for ( i = 0; i < graph->vertexs; i++ ) { scanf("%c", &graph->adjlist[i].info); graph->adjlist[i].next = NULL; getchar(); } graph->brim = 0; for ( i = 0; i < graph->vertexs; i++ ) { printf("输入与节点%c相邻的节点和权值,#号键结束\n", graph->adjlist[i].info); for ( j = 0; j < graph->vertexs; j++ ) { scanf("%c", &c); if ( c == ‘#‘ ) { getchar(); break; } scanf("%d", &num); getchar(); for ( k = 0; k < graph->vertexs; k++ ) { if ( graph->adjlist[k].info != c ) continue; if ( graph->adjlist[k].next == NULL ) graph->adjlist[k].next = make_node(i, num); else { tmp = graph->adjlist[k].next; while ( tmp->next != NULL ) tmp = tmp->next; tmp->next = make_node(i, num); } graph->brim++; } } } graph->brim /= 2; } static void dfs_graph(Graph * graph, bool visited[], const int i); void g_depth_first_search(Graph * graph) { bool visited[graph->vertexs]; int i; for ( i = 0; i < graph->vertexs; i++ ) visited[i] = false; visited[0] = true; dfs_graph(graph, visited, 0); } static void dfs_graph(Graph * graph, bool visited[], const int i) { Arc_node * tmp; printf("%c\t", graph->adjlist[i].info); tmp = graph->adjlist[i].next; while ( tmp != NULL ) { if ( !visited[tmp->pos] ) { visited[tmp->pos] = true; dfs_graph(graph, visited, tmp->pos); } tmp = tmp->next; } } void g_breadth_first_search(Graph * graph) { Queue queue; bool visited[graph->vertexs]; int pos; int i; Arc_node * tmp; q_init(&queue); for ( i = 0; i < graph->vertexs; i++ ) visited[i] = false; visited[0] = true; q_push(&queue, 0); while ( !q_empty(&queue) ) { pos = q_front(&queue); printf("%c\t", graph->adjlist[pos].info); tmp = graph->adjlist[pos].next; while ( tmp != NULL ) { if ( !visited[tmp->pos] ) { visited[tmp->pos] = true; q_push(&queue, tmp->pos); } tmp = tmp->next; } q_pop(&queue); } printf("\n"); } static void init_prim(Graph * graph, Graph * prim_tree); void g_prim(Graph * graph, Graph * prim_tree) { bool visited[graph->vertexs]; int i, j, k; int power, pos; Arc_node * tmp; for ( i = 0; i < graph->vertexs; i++ ) visited[i] = false; init_prim(graph, prim_tree); visited[0] = true; for ( i = 0; i < graph->vertexs; i++ ) { power = INT_MAX;//limits.h for ( j = 0; j < graph->vertexs; j++ ) { if ( visited[j] ) { tmp = graph->adjlist[j].next; while ( tmp != NULL ) { if ( power > tmp->distance && !visited[tmp->pos] ) { power = tmp->distance; pos = tmp->pos; k = j; } tmp = tmp->next; } } } if ( !visited[pos] ) { if ( prim_tree->adjlist[k].next == NULL ) { prim_tree->adjlist[k].next = make_node(pos, power); } else { tmp = prim_tree->adjlist[k].next; while ( tmp->next != NULL ) tmp = tmp->next; tmp->next = make_node(pos, power); } visited[pos] = true; } } } static void init_prim(Graph * graph, Graph * prim_tree) { int i; for ( i = 0; i < graph->vertexs; i++ ) { prim_tree->adjlist[i].info = graph->adjlist[i].info; prim_tree->adjlist[i].next = NULL; } prim_tree->vertexs = graph->vertexs; prim_tree->brim = graph->brim; } //kruskal typedef struct { int head; int tail; int power; } Edge; static void init_kruskal(Graph * graph, Graph * kruskal_tree); static void my_sort(Edge * arr, int size); void kruskal(Graph * graph, Graph * kruskal_tree) { int visited[graph->vertexs]; int i, j; Edge edge[graph->brim]; int v1, v2, vs1, vs2; Arc_node * cur, * tmp; for ( i = 0; i < graph->vertexs; i++ ) visited[i] = i; for ( i = 0, j = 0; i < graph->vertexs; i++ ) { cur = graph->adjlist[i].next; while ( cur != NULL ) { if ( cur->pos > i ) { edge[j].head = i; edge[j].tail = cur->pos; edge[j].power = cur->distance; j++; } cur = cur->next; } } init_kruskal(graph, kruskal_tree); my_sort(edge, graph->brim); for ( i = 0; i < graph->brim; i += 1 ) { v1 = edge[i].head; v2 = edge[i].tail; vs1 = visited[v1]; vs2 = visited[v2]; if ( vs1 != vs2 ) { if ( kruskal_tree->adjlist[v1].next == NULL ) { kruskal_tree->adjlist[v1].next = make_node(v2, edge[i].power); } else { tmp = kruskal_tree->adjlist[v1].next; while ( tmp->next != NULL ) tmp = tmp->next; tmp->next = make_node(v2, edge[i].power); } for ( j = 0; j < graph->vertexs; j++ ) { if ( visited[j] == vs2 ) visited[j] = vs1; } } } } static void init_kruskal(Graph * graph, Graph * kruskal_tree) { int i; kruskal_tree->vertexs = graph->vertexs; kruskal_tree->brim = graph->brim; for ( i = 0; i < graph->vertexs; i++ ) { kruskal_tree->adjlist[i].info = graph->adjlist[i].info; kruskal_tree->adjlist[i].next = NULL; } } static void my_sort(Edge * arr, int size) { int i, j; Edge tmp; for ( i = 0; i < size - 1; i++ ) { for ( j = i + 1; j < size; j++ ) { if ( arr[i].power > arr[j].power ) { tmp.head = arr[i].head; tmp.tail = arr[i].tail; tmp.power = arr[i].power; arr[i].head = arr[j].head; arr[i].tail = arr[j].tail; arr[i].power = arr[j].power; arr[j].head = tmp.head; arr[j].tail = tmp.tail; arr[j].power = tmp.power; } } } } int main(void) { Graph graph; Graph prim_tree; Graph kruskal_tree; Arc_node * node; int i; g_create(&graph); printf("brim = %d\n", graph.brim); for ( i = 0; i < graph.vertexs; i++ ) { printf("%c\t", graph.adjlist[i].info); node = graph.adjlist[i].next; while ( node != NULL ) { printf("%d %d\t", node->distance, node->pos); node = node->next; } printf("\n"); } printf("\n"); // g_depth_first_search(&graph); // printf("\n"); // g_breadth_first_search(&graph); kruskal(&graph, &kruskal_tree); printf("brim = %d\n", kruskal_tree.brim); for ( i = 0; i < kruskal_tree.vertexs; i++ ) { printf("%c\t", kruskal_tree.adjlist[i].info); node = kruskal_tree.adjlist[i].next; while ( node != NULL ) { printf("%d %d\t", node->distance, node->pos); node = node->next; } printf("\n"); } printf("\n"); return 0; }
aqueue.h
#ifndef _QUEUE_H #define _QUEUE_H #define MAXSIZE 10 typedef struct queue { int * arr; int front; int rear; } Queue; void q_init(Queue * queue);//初始化 void q_push(Queue * queue, const int data);//入队 void q_pop(Queue * queue);//出队 bool q_empty(Queue * queue);//为空 bool q_full(Queue * queue);//为满 int q_size(Queue * queue);//队大小 int q_front(Queue * queue);//队头元素 int q_back(Queue * queue);//队尾元素 void q_destroy(Queue * queue);//销毁 #endif //_QUEUE_h
aqueue.c
#include <stdio.h> #include <stdlib.h> #include <assert.h> #include <stdbool.h> #include "aqueue.h" void q_init(Queue * queue) { queue->arr = (int *)malloc( sizeof(int) * MAXSIZE );//初始化数组 assert(queue->arr != NULL); queue->front = 0; queue->rear = 0; } void q_push(Queue * queue, const int data) { if ( q_full(queue) ) return; queue->arr[queue->rear++] = data;//入队,队尾+1 queue->rear = queue->rear % MAXSIZE;//如果队尾 } void q_pop(Queue * queue) { if ( q_empty(queue) ) return; queue->front = ++queue->front % MAXSIZE;//front+1,对MAXSIZE取余 } bool q_empty(Queue * queue) { return queue->front == queue->rear; } bool q_full(Queue * queue) { return queue->front == (queue->rear + 1) % MAXSIZE; } int q_size(Queue * queue) { return (queue->rear - queue->front) % MAXSIZE; } int q_front(Queue * queue) { assert( !q_empty(queue) ); return queue->arr[queue->front]; } int q_back(Queue * queue) { assert( !q_empty(queue) ); return queue->arr[queue->rear - 1]; } void q_destroy(Queue * queue) { free(queue->arr); }
以上是关于邻接表c源码(构造邻接矩阵,深度优先遍历,广度优先遍历,最小生成树prim,kruskal算法)的主要内容,如果未能解决你的问题,请参考以下文章
用c语言编程 1创建图的邻接矩阵和邻接表 2验证图的深度优先、广度优先遍历算法 3验证最短路径