您的位置:首页 > 理论基础 > 数据结构算法

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

2017-08-28 00:24 417 查看
结构体及相关函数声明如下:

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);
}
//---------
b65d
-----------------------------------------------------------------


关键在于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题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息