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

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

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 list
void 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题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
静态存储链表是指使用数组来模拟链表的存储方式。其实现方式如下: ```c #define MAXSIZE 100 // 静态链表的最大长度 typedef struct { int data; // 数据域 int next; // 指针域,存储下一个元素的位置 } Node; Node List[MAXSIZE]; // 静态链表 int head; // 静态链表头指针 // 初始化静态链表 void InitList() { for (int i = 0; i < MAXSIZE; i++) { List[i].next = -2; // 初始时,所有节点都是空节点 } head = -1; // 链表为空 } // 在静态链表末尾插入元素 int Insert(int elem) { int i = 0; while (List[i].next != -2 && i < MAXSIZE) { i++; } if (i == MAXSIZE) { return -1; // 静态链表已满,插入失败 } List[i].data = elem; // 将数据存入新节点 List[i].next = -1; // 新节点为末尾节点 if (head == -1) { // 如果链表为空,则头指针指向第一个节点 head = i; } else { // 否则,找到末尾节点并将其指向新节点 int j = head; while (List[j].next != -1) { j = List[j].next; } List[j].next = i; } return i; // 返回新节点位置 } // 删除静态链表中的元素 int Delete(int elem) { if (head == -1) { // 链表为空,删除失败 return -1; } int i = head; int j = -1; while (i != -1 && List[i].data != elem) { // 找到要删除的节点位置 j = i; i = List[i].next; } if (i == -1) { // 如果未找到,删除失败 return -1; } if (i == head) { // 如果删除的是头节点 head = List[i].next; } else { // 否则,将前一个节点指向后一个节点 List[j].next = List[i].next; } List[i].next = -2; // 将删除的节点置为空节点 return i; // 返回删除的节点位置 } ``` 以上代码实现静态存储链表的基本操作,包括初始化、插入和删除。需要注意的是,由于静态链表是使用数组来模拟链表,因此在存储时需要额外开辟数组空间。同时,由于静态链表的大小是固定的,因此在插入和删除时需要注意数组的边界问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值