邻接表

9 篇文章 0 订阅

description

.h 文件

#include <stdio.h>
#include <stdlib.h>


#define handler_error(msg) \
    do { perror(msg); return EXIT_FAILURE; } while (1)

struct arcnode{
    size_t data;
    struct arcnode *next;
};

struct vexnode{
    size_t id; 
    struct arcnode *firstnode;
};

struct graph{
    size_t node_number;
    size_t edge_number;
};



int malloc_graph(struct graph **g);
struct vexnode *malloc_vexnode(size_t length, struct graph *g);       //according to argv[] input

struct vexnode *realloc_vexnode(struct vexnode old_vex[], size_t new_length, struct graph *g);

size_t generate_vexnode(struct vexnode head[],struct graph *g);

struct vexnode *search_vexnode_by_id(struct vexnode head[], const size_t id, struct graph *g);

int judge_node_by_i_j(struct vexnode head[], const size_t i, const size_t j, struct graph *g);

int add_arcnode_by_i_j(struct vexnode head[], struct graph *g, const size_t i, const size_t j);

int del_arcnode_by_i_j(struct vexnode head[], struct graph *g, const size_t i, const size_t j);

void destroy_vexnode_only(struct vexnode head[], struct graph *g);

void destroy_vexnode_and_arcnode(struct vexnode head[], struct graph *g);

.c 文件

#include "aja_table.h"


int malloc_graph(struct graph **g)
{
    if ((*g = (struct graph *)malloc(sizeof(struct graph))) == NULL) 
        return -1;
    (*g)->edge_number = 0;
    (*g)->node_number = 0;
    return 0;
}

struct vexnode *malloc_vexnode(size_t length, struct graph *g)       //according to argv[] input
{
    struct vexnode *head = NULL;
    if ((head = (struct vexnode *)malloc(sizeof(struct vexnode)*length)) == NULL) {
        printf("malloc_vexnode error\n");
        return NULL;
    }
    g->node_number = length;
    //printf("malloc_vexnode success, length: %lu\n", length);
    return head;
}

struct vexnode *realloc_vexnode(struct vexnode old_vex[], size_t new_length, struct graph *g)
{
    struct vexnode *new_vex = NULL;
    if ((new_vex = (struct vexnode *)malloc(sizeof(struct vexnode)*new_length)) == NULL)
        return NULL;

    g->node_number = new_length;

    struct vexnode *old_temp = old_vex, *new_temp = new_vex;

    size_t old_length = g->node_number;

    for (size_t i = 1; i <= old_length; i++) {
        new_temp->id = old_temp->id;
        new_temp->firstnode = old_temp->firstnode;
        old_temp++;
        new_temp++;
    }
    destroy_vexnode_only(old_vex, g);

    for ( ; old_length <= new_length; old_length++) {
        new_temp->id = old_length;
        new_temp->firstnode = NULL;
        new_temp++;
    }

    return new_vex;
}

size_t generate_vexnode(struct vexnode head[], struct graph *g)
{

    struct vexnode *vex_head = head;            
    size_t id = 1;
    size_t length = g->node_number;

    //printf("generate ():\n");
    //printf("%lu %lu\n", length, g->node_number);
    //getchar();

    for (size_t i = 1; i <= length; i++) {
        //printf("try %lu\n", id);

        vex_head->id = i;
        vex_head->firstnode = NULL;
        vex_head++;
    }
    return id;
}

struct vexnode *search_vexnode_by_id(struct vexnode head[], const size_t id, struct graph *g)
{
    size_t length = g->node_number;
    struct vexnode *pointer = head;

    for (size_t i = 1; i <= length; i++) {
        if (id == pointer->id)
            return pointer;
        else
            pointer++;
    }
    return NULL;
}

int judge_node_by_i_j(struct vexnode head[], const size_t i, const size_t j, struct graph *g)
{
    struct vexnode *pointer = head;
    struct vexnode *vex_head = NULL;
    if ((vex_head = search_vexnode_by_id(pointer, i, g)) == NULL)
        return -2;      //failed

    struct arcnode *arc_head = vex_head->firstnode;
    while (arc_head != NULL) {
        if (j == arc_head->data)
            return 0;       //success
        arc_head = arc_head->next;
    }
    return -1;      //failed
}

int add_arcnode_by_i_j(struct vexnode head[], struct graph *g, const size_t i, const size_t j)
{
    struct vexnode *vec_result = NULL;
    if ((vec_result = search_vexnode_by_id(head, i, g)) == NULL)
        return -1;

    struct arcnode *arc_now = vec_result->firstnode; 

    struct arcnode *arc_insert = NULL;
    if ((arc_insert = (struct arcnode *)malloc(sizeof(struct arcnode))) == NULL)
        return -1;
    arc_insert->data = j;

    if (arc_now == NULL) {   //first time
        arc_insert->next = arc_now;
        vec_result->firstnode = arc_insert;
    } else {        //not the first time
        arc_insert->next = arc_now;
        vec_result->firstnode = arc_insert;
    }
    g->edge_number++;
    return 0;
}

int del_arcnode_by_i_j(struct vexnode head[], struct graph *g, const size_t i, const size_t j)
{
    struct vexnode *vex_result = NULL;
    if ((vex_result = search_vexnode_by_id(head, i, g)) == NULL)
        return -1;

    struct arcnode *arc_pre = vex_result->firstnode;

    if (arc_pre == NULL)
        return -1;
    if (arc_pre->next == NULL && arc_pre->data != j)
        return -1;
    if (arc_pre->next == NULL && arc_pre->data == j) {
        g->edge_number--; 
        vex_result->firstnode = NULL;
        free(arc_pre);
        printf("success del only one node\n");
        return 0;
    }
    struct arcnode *arc_now = arc_pre->next;
    while (arc_now != NULL) {
        if (arc_now->data == j) {
            printf("success delete node\n") ;

            arc_pre->next = arc_now->next;
            free(arc_now);
            return 0;
        }
        arc_pre = arc_now;
        arc_now = arc_now->next;
    }
    return -1;
}

void destroy_vexnode_only(struct vexnode head[], struct graph *g)
{
    struct vexnode *vex_head = head, *vex_temp = head++;

    if (vex_head == NULL)
        return ;
    if (vex_temp == NULL) {
        free(head);
        return ;
    }

    size_t length = g->node_number;

    for (size_t i = 1; i <= length; i++) {
        vex_temp = vex_head++;
        free(vex_head);
        vex_head = vex_temp;
    }
}

void destroy_vexnode_and_arcnode(struct vexnode head[], struct graph *g)
{
    struct vexnode *vex_head = head;
    size_t length = g->node_number;

    for (size_t i = 1; i <= length; i++) {
        struct arcnode *arc_now = vex_head->firstnode; 
        while (arc_now != NULL) {
            struct arcnode *temp = arc_now->next; 
            free(arc_now);
            arc_now = temp;
        }
        vex_head++; 
    }
}

main.c 测试文件

#include "./aja_table.h" 
#include <unistd.h>


int main(int argc, char *argv[])
{
    // file_name, number
    if (argc < 2)
        handler_error("argument is not good\n");

    char *file_name = argv[1];
    size_t file_nodes = (size_t)atoi(argv[2]);

    struct graph *graph_test = NULL;
    if (malloc_graph(&graph_test) == -1)
        handler_error("malloc graph error\n");

    struct vexnode *vex_head = NULL;
    if ((vex_head = malloc_vexnode(file_nodes, graph_test)) == NULL)
        handler_error("malloc vexnode error\n");

    generate_vexnode(vex_head, graph_test);

    FILE *file = NULL;
    if ((file = fopen(file_name, "r")) == NULL)
        handler_error("fopen file error");


    struct vexnode *vex_temp = NULL;
    size_t i, j;
    while (fscanf(file, "%lu %lu", &i, &j) != EOF) {

        static int readtime = 1;
        static int inserttime = 0;
        printf("%d  : i = %lu, j = %lu\n", readtime++, i, j);


        if ((vex_temp = search_vexnode_by_id(vex_head, i, graph_test)) == NULL)
            handler_error("line:33 search error\n");

        int judge = 1;
        if ((judge = judge_node_by_i_j(vex_head, i, j, graph_test)) == 0)
            continue;
        else if (judge == -1) {

            int insert_result = 1;
            if ((insert_result = add_arcnode_by_i_j(vex_head, graph_test, i, j)) == -1)
                handler_error("line:40 add arcnode error\n");
            else if (insert_result == 0)
                printf("insert: %d times\n\n", ++inserttime);

        } else if (judge == -2) 
            handler_error("line:41 no vexnode in vex_head!\n");
        else
            handler_error("line:44 unknown result\n");
    }


    printf("graph:  nodes:%lu  edges:%lu\n", graph_test->node_number,graph_test->edge_number);


    struct vexnode *temp = vex_head;
    struct arcnode *temp2 = NULL;
    size_t node_of_vex = graph_test->node_number;


    /*testtest !!!! */
    /*
    temp2 = temp->firstnode;
    int x = 1;
    while (temp2 != NULL) {
        printf("time: %d  data = %lu\n", x++, temp2->data);
        temp2=temp2->next;
    }
    getchar();
    */


    //printf("\n\nnode of vex : %lu\n", node_of_vex);
    //getchar();

    //================== test result ========================
    for (size_t i = 1; i < node_of_vex; i++) {
        printf("\n=====  node:%lu ======\n", temp->id);
        printf("aja nodes:  ");
        temp2 = temp->firstnode;
        while (temp2 != NULL) {
            printf("  %lu  ", temp2->data);
            temp2 = temp2->next;
        }
        printf("\n");
        temp++;
    }

    fclose(file);
    destroy_vexnode_and_arcnode(vex_head, graph_test);

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值