静态双向链表的单数组实现

来源:互联网 发布:淘宝规定卖家发货时间 编辑:程序博客网 时间:2024/06/05 08:27

结构体及相关函数声明如下:

typedef struct ITEM {    int key;    void * statellite;} item_t;typedef struct STATIC_SINGLE_ARRAY_DOUBLE_LINKED_LIST{    int size;    int count;    int head;    int free;    item_t * array;} SSADLL;void SSADLL_traverse(SSADLL * L);SSADLL* SSADLL_init(int size);item_t* SSADLL_get_object(SSADLL * L, int location);item_t* SSADLL_get_next(SSADLL * L, int location);item_t* SSADLL_get_prev(SSADLL * L, int location);int SSADLL_free(SSADLL * L, int location);int SSADLL_allocate(SSADLL * L);int SSADLL_insert(SSADLL * L, item_t item);int SSADLL_search(SSADLL * L, item_t item);int SSADLL_delete(SSADLL * L, item_t item);

各函数实现如下:

//functions for static single array double linked listvoid SSADLL_traverse(SSADLL * L) {    if (L == NULL) {        fprintf(stderr, "Not initialized.\n");        return;    }    if (L->head == 0) {        fprintf(stderr, "Empty linked list.\n");    }    int location = L->head;    printf("Total elements number is %3d. Linked list size is %3d.\n", L->count, L->size);    while (location != 0) {        printf("%3d item prev is %3d, location is %3d, next is %3d.\n", \            SSADLL_get_object(L, location)->key, SSADLL_get_prev(L, location)->key, location, \            SSADLL_get_next(L, location)->key);        location = SSADLL_get_next(L, location)->key;    }    int free = L->free;    while (free != 0) {        printf("Free space is %3d, next is: %3d\n", free, SSADLL_get_next(L, free)->key);        free = SSADLL_get_next(L, free)->key;    }}item_t* SSADLL_get_object(SSADLL * L, int location) {    return L->array + 3 * (location - 1);}item_t* SSADLL_get_next(SSADLL * L, int location) {    return L->array + 3 * (location - 1) + 1;}item_t* SSADLL_get_prev(SSADLL * L, int location) {    return L->array + 3 * (location - 1) + 2;}SSADLL* SSADLL_init(int size) {    SSADLL * L = (SSADLL*)malloc(sizeof(SSADLL));    if (!L) {        fprintf(stderr, "Static single array double linked list init fail.\n");        return NULL;    }    L->size = size;    L->count = 0;    L->head = 0;    L->free = size;    L->array = (item_t*)calloc(size * 3, sizeof(item_t));    if (!L->array) {        fprintf(stderr, "Static single array double linked list init fail.\n");        return NULL;    }    for (int i = size; i > 0; i--) {        SSADLL_get_next(L, i)->key = i - 1;    }    return L;}int SSADLL_free(SSADLL * L, int location) {    if (location <= 0 || location > L->size) {        fprintf(stderr, "Out of range.\n");        return 0;    }    SSADLL_get_next(L, location)->key = L->free;    L->free = location;    return 1;}int SSADLL_allocate(SSADLL * L) {    if (L->free == 0) {        fprintf(stderr, "Out of range.\n");        return 0;    }    int x = L->free;    L->free = SSADLL_get_next(L, L->free)->key;    return x;}int SSADLL_insert(SSADLL * L, item_t item) {    if (L == NULL) {        fprintf(stderr, "Not initialized.\n");        return 0;    }    int obj = SSADLL_allocate(L);    if (obj == 0) {        fprintf(stderr, "Out of range.\n");        return obj;    }    *SSADLL_get_object(L, obj) = item;    SSADLL_get_next(L, obj)->key = L->head;    SSADLL_get_prev(L, obj)->key = 0;    L->count++;    if (L->head != 0)        SSADLL_get_prev(L, L->head)->key = obj;    L->head = obj;    return obj;}int SSADLL_search(SSADLL * L, item_t item) {    if (L == NULL) {        fprintf(stderr, "Not initialized.\n");        return 0;    }    if (L->head == 0) {        fprintf(stderr, "Empty linked list.\n");        return 0;    }    int location = L->head;    while (location != 0) {        if (SSADLL_get_object(L, location)->key == item.key) {            return location;        }        location = SSADLL_get_next(L, location)->key;    }    fprintf(stderr, "Item cannot be found.\n");    return 0;}int SSADLL_delete(SSADLL * L, item_t item) {    int location = SSADLL_search(L, item);    if (location == 0) {        fprintf(stderr, "Delete fail.\n");        return 0;    }    if (SSADLL_get_next(L, location)->key) {        SSADLL_get_prev(L, SSADLL_get_next(L, location)->key)->key = SSADLL_get_prev(L, location)->key;    }    if (SSADLL_get_prev(L, location)->key) {        SSADLL_get_next(L, SSADLL_get_prev(L, location)->key)->key = SSADLL_get_next(L, location)->key;    }    if (location == L->head) {        L->head = SSADLL_get_next(L, location)->key;    }    L->count--;    return SSADLL_free(L, location);}//--------------------------------------------------------------------------

关键在于next和prev的获取,可用如下代码进行测试:

void test_for_SSADLL() {    SSADLL * L = SSADLL_init(SIZE);    for (int i = 0; i < 10; i++) {        item_t item = {i + 10, NULL};        SSADLL_insert(L,item);    }    SSADLL_traverse(L);    for (int i = 0; i < 10; i++) {        item_t item = {i + 10, NULL};        SSADLL_delete(L, item);    }    SSADLL_traverse(L);    printf("-------------------------------------------------------------------\n");    for (int i = 0; i <= 10; i++) {        item_t item = {i + 10, NULL};        SSADLL_insert(L, item);    }    for (int i = 4; i >= -2; i--) {        item_t item = {i + 10, NULL};        SSADLL_delete(L, item);    }    for (int i = 0; i <= 10; i++) {        item_t item = {i - 10, NULL};        SSADLL_insert(L, item);    }    for (int i = -10; i <= 17; i++) {        item_t item = {i, NULL};        SSADLL_delete(L, item);    }    SSADLL_traverse(L);}

关于静态双向链表的单数组表示的相关内容可见算法导论第三版10.3小结,以及10.3-2题。