动手实现 数据结构 之 “十字链表”

来源:互联网 发布:手机喊麦用什么软件 编辑:程序博客网 时间:2024/05/01 20:15



与邻接链表图非常相似,相对而言多了前向边的处理


使用 C语言 十字链表 实现了: 添加边,删除边,查找边的功能

#include <stdio.h>#include <stdlib.h>typedef int bool;#define false 0;#define true 1;typedef struct Edge {    double weight;    int source;    int dest;    struct Edge * linkPre;    struct Edge * linkNex;} Edge;typedef struct CrossListMap {    int n;    int * data;    struct Edge ** headPre;    struct Edge ** headNex;} CrossListMap;void            InitMap(struct CrossListMap * map, int n);void            DestroyMap(struct CrossListMap * map);struct Edge *   AddEdge(struct CrossListMap *   map,                        unsigned int            source/*0~n-1*/,                        unsigned int            dest/*0~n-1*/,                        double                  weight);bool            RemoveEdge(struct CrossListMap * map,                           unsigned int          source/*0~n-1*/,                           unsigned int          dest/*0~n-1*/);struct Edge *   GetEdge(struct CrossListMap *   map,                        unsigned int            source/*0~n-1*/,                        unsigned int            dest/*0~n-1*/);void            print1(struct CrossListMap *    map);void            print2(struct CrossListMap *    map);// 初始化有 n 个节点的图void InitMap(struct CrossListMap * map, int n) {    map->n = n;    map->data = (int*)malloc(n*sizeof(int));    map->headPre = (struct Edge**)malloc(n*sizeof(struct Edge*));    map->headNex = (struct Edge**)malloc(n*sizeof(struct Edge*));    for(int i=0; i<n; i++) {        map->headPre[i] = NULL;        map->headNex[i] = NULL;    }}void DestroyMap(struct CrossListMap * map) {    free(map->data);    for(int i=0; i<map->n; i++) {        struct Edge* nex;        for (struct Edge* e=map->headNex[i]; e!=NULL; e=nex) {            nex = e->linkNex;            free(e);        }    }    free(map->headPre);    free(map->headNex);}struct Edge * AddEdge(struct CrossListMap * map,                      unsigned int          source/*0~n-1*/,                      unsigned int          dest/*0~n-1*/,                      double                weight){    if(map->n < source || map->n < dest || map == NULL) return NULL;    struct Edge * edge = (struct Edge *)malloc(sizeof(struct Edge));    edge->weight = weight;    edge->source = source;    edge->dest = dest;        //-------------部分一 后向边的处理-------------    struct Edge * nex1 = map->headNex[source];    struct Edge * nex2 = nex1;    // 查找插入位置    while (nex2 != NULL) {        if(dest < nex2->dest)            break;        else if(dest == nex1->dest)            return NULL;        nex1 = nex2;        nex2 = nex2->linkNex;    }    // 插入新的边为第一条边    if (nex1 == NULL || dest < nex1->dest) {        map->headNex[source] = edge;    } else {        nex1->linkNex = edge;    }    edge->linkNex = nex2;        //-------------部分二 前向边的处理-------------    struct Edge * pre1 = map->headPre[dest];    struct Edge * pre2 = pre1;    // 查找插入位置    while (pre2 != NULL) {        if(source < pre2->source)            break;        else if(source == pre1->source)            return NULL;        pre1 = pre2;        pre2 = pre2->linkPre;    }    // 插入新的边为第一条边    if (pre1 == NULL || source < pre1->source) {        map->headPre[dest] = edge;    } else {        pre1->linkPre = edge;    }    edge->linkPre = pre2;    return edge;}bool RemoveEdge(struct CrossListMap *   map,                unsigned int            source/*0~n-1*/,                unsigned int            dest/*0~n-1*/) {    if(map->n < source || map->n < dest || map == NULL) return false;        //-------------部分一 后向边的处理-------------    struct Edge * nex1 = map->headNex[source];    struct Edge * nex2 = nex1;    while(nex2 != NULL && nex2->dest < dest && nex2->linkNex != NULL) {        nex1 = nex2;        nex2 = nex2->linkNex;    }    if(nex2 == NULL || nex2->dest != dest) return false;        if(nex1 == nex2) {        map->headNex[source] = nex2->linkNex;    } else {        nex1->linkNex = nex2->linkNex;    }            //-------------部分二 前向边的处理-------------    struct Edge * pre1 = map->headPre[dest];    struct Edge * pre2 = pre1;    while(pre2 != NULL && pre2->source < source && pre2->linkPre != NULL) {        pre1 = pre2;        pre2 = pre2->linkPre;    }    if(pre2 == NULL || pre2->source != source) return false;        if(pre1 == pre2) {        map->headPre[dest] = pre2->linkPre;    } else {        pre1->linkPre = pre2->linkPre;    }        free(nex2);    return true;}struct Edge * GetEdge(struct CrossListMap * map,                      unsigned int          source/*0~n-1*/,                      unsigned int          dest/*0~n-1*/){    if(map->n < source || map->n < dest || map == NULL) return NULL;    struct Edge * edge = map->headNex[source];    while(edge != NULL && edge->dest < dest && edge->linkNex != NULL) {        edge = edge->linkNex;    }    if(edge == NULL || edge->dest != dest) return NULL; // 不存在从 source 到 dest 这条边    return edge;}void print(struct CrossListMap * map) {    for (int i=0; i<map->n; i++)        for (struct Edge * e=map->headNex[i]; e!=NULL; e=e->linkNex)            printf("from: %d to: %d, weight: %.1lf\n", e->source, e->dest, e->weight);}void print2(struct CrossListMap * map) {    for (int i=0; i<map->n; i++)        for (struct Edge * e=map->headPre[i]; e!=NULL; e=e->linkPre)            printf("%d comes from: %d, weight: %.1lf\n", e->dest, e->source, e->weight);}int main(void){    CrossListMap map;    InitMap(&map, 4);    //      图,起点,终点,权值    AddEdge(&map, 0, 1, 3.0);    AddEdge(&map, 0, 2, 3.0);    AddEdge(&map, 2, 0, 4.0);    AddEdge(&map, 2, 3, 4.0);    AddEdge(&map, 3, 0, 5.0);    AddEdge(&map, 3, 1, 5.0);    AddEdge(&map, 3, 2, 5.0);    RemoveEdge(&map, 0, 1);    print(&map);    print2(&map);    struct Edge * searchEdge = GetEdge(&map, 0, 1);    if(searchEdge != NULL)        printf("Weight of edge 0 to 2 is %.1lf\n", searchEdge->weight);        DestroyMap(&map);    return 0;}


0 0
原创粉丝点击