• 邻接表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相邻的节点和权值,#号键结束
    ", 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	", 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	", 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("
    ");
    }
    
    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
    ", graph.brim);
        for ( i = 0; i < graph.vertexs; i++ )
        {
            printf("%c	", graph.adjlist[i].info);
            node = graph.adjlist[i].next;
            while ( node != NULL )
            {
                printf("%d %d	", node->distance, node->pos);
                node = node->next;
            }
            printf("
    ");
        }
        printf("
    ");
    
    //    g_depth_first_search(&graph);
    //    printf("
    ");
    //    g_breadth_first_search(&graph);
    
        kruskal(&graph, &kruskal_tree);
        printf("brim = %d
    ", kruskal_tree.brim);
        for ( i = 0; i < kruskal_tree.vertexs; i++ )
        {
            printf("%c	", kruskal_tree.adjlist[i].info);
            node = kruskal_tree.adjlist[i].next;
            while ( node != NULL )
            {
                printf("%d %d	", node->distance, node->pos);
                node = node->next;
            }
            printf("
    ");
        }
        printf("
    ");
    
        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);
    }
  • 相关阅读:
    LeetCode 1109 航班预定统计
    leetcode 138 复制带随机指针的链表
    maven导入org.apache.pdfbox
    Intellij Idea 通过svn或者git提交代码时速度慢的解决办法
    java LocalDateTime 加减当前时间
    git命令--拉取代码和切换分支
    Intellij IDEA插件Free Mybatis plugin
    MySQL 生成随机字符串 uuid
    最新版Navicat Premium v15.0.26 中文破解
    算法——二分法查找
  • 原文地址:https://www.cnblogs.com/ITgaozy/p/5200643.html
Copyright © 2020-2023  润新知