鏈表(Linked List)的C語言實現__C語言

來源:互聯網
上載者:User

鏈表中的各對象按線性順序排列,而其順序是由各個對象裡的指標所決定的。
鏈表有多種形式,它可以是單連結的或者雙連結的,可以是已排序的或未排序的,可以是迴圈的或非迴圈的。
定義的結構體以及函數如下:

typedef struct SINGLE_LINKED_LIST{    Node * head;    Node * tail;} SLL;typedef struct CIRCULAR_SINGLE_LINKED_LIST{    Node * head;    Node * tail;} CSLL;typedef struct DOUBLE_LINKED_LIST{    Node * head;    Node * tail;} DLL;typedef struct CIRCULAR_DOUBLE_LINKED_LIST_WITH_SENTINEL{    Node * nil;} CDLLS;void linked_list_traverse(Node * L);void linked_list_free(Node* L);Node* single_linked_list_insert(SLL * L, item_t item);Node* single_linked_list_search(SLL * L, item_t item);int single_linked_list_delete(SLL * L, Node * node);Node* circular_single_linked_list_insert(CSLL * L, item_t item);Node* circular_single_linked_list_search(CSLL * L, item_t item);int circular_single_linked_list_delete(CSLL * L, Node * node);Node* double_linked_list_insert(DLL * L, item_t  item);Node* double_linked_list_search(DLL * L, item_t item);int double_linked_list_delete(DLL * L, Node * node);CDLLS* circular_double_linked_list_with_sentinel_init();Node* circular_double_linked_list_with_sentinel_insert(CDLLS * L, item_t item);Node* circular_double_linked_list_with_sentinel_search(CDLLS * L, item_t item);int circular_double_linked_list_with_sentinel_delete(CDLLS * L, Node * node);

幾個公用函數如下:

//functions for all kind of linked listvoid linked_list_traverse(Node* L) {    if (L == NULL) {        printf("Empty Linked List.\n");    }    Node * pos = L;    while (pos != NULL) {        printf("%2d is in location:%9p. prev is %9p. next is %9p.\n", pos->item.key, \            pos, pos->prev, pos->next);        pos = pos->next;        if (pos == L) return;    }}void linked_list_free(Node* L) {    Node * pos = L;    Node * f = L;    while (pos != NULL && pos != L) {        f = pos;        pos = pos->next;        free(f);    }}//-----------------------------------------------------------------------

單連結的未排序非迴圈鏈表可以如如下實現:

//functions for single linked listNode* single_linked_list_insert(SLL * L, item_t item) {    Node * node = (Node*)malloc(sizeof(Node));    node->item = item;    node->prev = NULL;    node->next = L->head;    if (L->tail == NULL)        L->tail = node;    L->head = node;    return node;}Node* single_linked_list_search(SLL * L, item_t item) {    if (L->head == NULL) {        fprintf(stderr, "The single linked list is empty.\n");        return NULL;    }    Node * pos = L->head;    while (pos != NULL) {        if (item.key == pos->item.key)            return pos;        pos = pos->next;    }    fprintf(stderr, "The item cannot be found.\n");    return NULL;}int single_linked_list_delete(SLL * L, Node * node) {    if (L->head == NULL) {        fprintf(stderr, "The single linked list is empty.\n");        return 0;    }    if (node == NULL) {        fprintf(stderr, "The node is NULL.\n");        return 0;    }    if (L->head == node) {        L->head = node->next;        if (L->head == NULL)            L->tail = NULL;        return 1;    }    Node * pos = L->head;    while (pos != NULL && pos->next != node) {        pos = pos->next;    }    if (pos->next = node) {        if (node == L->tail)            L->tail = pos;        pos->next = pos->next->next;        return 1;    }    fprintf(stderr, "No such node in linked list.\n");    return 0;}int single_linked_list_reverse(SLL * L) {    if (L->head == NULL) {        fprintf(stderr, "The single linked list is empty.\n");        return 0;    }    L->tail = L->head;    Node *pre, *current, *next;    pre = L->head;    current = L->head->next;    L->head->next = NULL;    next = NULL;    while (current != NULL) {        next = current->next;        current->next = pre;        pre = current;        current = next;    }    L->head = pre;    return 1;}//------------------------------------------------------------------------

各個函數的功能均可見其函數名與傳回值。使用SLL時動態分配記憶體即可,如:

void test_for_single_linked_list() {    SLL * L = (SLL*)malloc(sizeof(SLL));    printf("%p\n", L->head);    item_t item = {10, NULL};    Node * node;    for (int i = 0; i < 10; i++) {        item.key = i + 10;        single_linked_list_insert(L, item);    }    printf("SLL head is in location:%p\n", L->head);    linked_list_traverse(L->head);    single_linked_list_reverse(L);    linked_list_traverse(L->head);    for (int i = -1; i <= 10; i++) {        item.key = i + 10;        node = single_linked_list_search(L, item);        if (node != NULL)            printf("Node %d in location %p delete :%d\n", node->item.key, node, \                single_linked_list_delete(L, node));        //printf("SLL tail is in location:%p\n", L->tail);    }    printf("---------------------------------------------\n");    for (int i = 0; i < 10; i++) {        item.key = i + 10;        single_linked_list_insert(L, item);    }    printf("SLL head is in location:%p\n", L->head);    linked_list_traverse(L->head);    for (int i = 11; i >= -1; i--) {        item.key = i + 10;        node = single_linked_list_search(L, item);        if (node != NULL)            printf("Node %d in location %p delete :%d\n", node->item.key, node, \                single_linked_list_delete(L, node));        //printf("SLL tail is in location:%p\n", L->tail);    }    linked_list_free(L->head);    free(L);}

雙連結的未排序非迴圈鏈表可如如下實現:

//functions for double linked listNode* double_linked_list_insert(DLL * L, item_t item) {    Node * node = (Node*)malloc(sizeof(Node));    node->prev = NULL;    node->item = item;    node->next = L->head;    if (L->head != NULL)        L->head->prev = node;    else        L->tail = node;    L->head = node;    return node;}Node* double_linked_list_search(DLL * L, item_t item) {    if (L->head == NULL) {        fprintf(stderr, "The double linked list is empty.\n");        return NULL;    }    Node * pos = L->head;    while (pos != NULL) {        if (pos->item.key == item.key)            return pos;        pos = pos->next;    }    fprintf(stderr, "The item cannot be found.\n");    return NULL;}int double_linked_list_delete(DLL * L, Node * node) {    if (L->head == NULL) {        fprintf(stderr, "The double linked list is empty.\n");        return 0;    }    if (node == NULL) {        fprintf(stderr, "The node is NULL.\n");        return 0;    }    if (node == L->tail)        L->tail = node->prev;    if (node->prev != NULL) {        node->prev->next = node->next;    } else {        L->head = node->next;    }    if (node->next != NULL) {        node->next->prev = node->prev;    }    return 1;}//----------------------------------------------------------------------------

注意要點與單連結的未排序非迴圈鏈表相同。測試可如下:

void test_for_double_linked_list() {    DLL * L = (DLL*)malloc(sizeof(DLL));    printf("%p\n", L->head);    item_t item = {10, NULL};    Node * node;    for (int i = 0; i < 10; i++) {        item.key = i + 10;        double_linked_list_insert(L, item);    }    printf("DLL head is in location:%p\n", L->head);    linked_list_traverse(L->head);    for (int i = -1; i <= 10; i++) {        item.key = i + 10;        node = double_linked_list_search(L, item);        if (node != NULL)            printf("Node %d in location %p delete :%d\n", node->item.key, node, \                double_linked_list_delete(L, node));        //printf("DLL tail is in location:%p\n", L->tail);    }    printf("---------------------------------------------\n");    for (int i = 0; i < 10; i++) {        item.key = i + 10;        double_linked_list_insert(L, item);    }    printf("DLL head is in location:%p\n", L->head);    linked_list_traverse(L->head);    for (int i = 11; i >= -1; i--) {        item.key = i + 10;        node = double_linked_list_search(L, item);        if (node != NULL)            printf("Node %d in location %p delete :%d\n", node->item.key, node, \                double_linked_list_delete(L, node));        //printf("DLL tail is in location:%p\n", L->tail);    }    linked_list_free(L->head);    free(L);}

單連結未排序的迴圈鏈表可如如下實現:

//functinos for circular single linked listNode* circular_single_linked_list_insert(CSLL * L, item_t item) {    Node * node = (Node*)malloc(sizeof(Node));    node->item = item;    node->prev = NULL;    if (L->head == NULL) {        L->head = node;        L->tail = node;        node->next = node;    } else {        node->next = L->head;        L->head = node;        L->tail->next = node;    }    return node;}Node* circular_single_linked_list_search(CSLL * L, item_t item) {    if (L->head == NULL) {        fprintf(stderr, "The circular single linked list is empty.\n");        return NULL;    }    Node * pos = L->head;    if (pos->item.key == item.key)        return pos;    else        pos = pos->next;    while (pos->item.key != item.key && pos != L->head) {        pos = pos->next;    }    if (pos != L->head)        return pos;    fprintf(stderr, "The item cannot be found.\n");    return NULL;}int circular_single_linked_list_delete(CSLL * L, Node * node) {    if (L->head == NULL) {        fprintf(stderr, "The circular single linked list is empty.\n");        return 0;    }    if (node == NULL) {        fprintf(stderr, "The node is NULL.\n");        return 0;    }    if (node == L->head && node == L->tail) {        L->head = NULL;        L->tail = NULL;        return 1;    } else if (node == L->head) {        L->head = node->next;        L->tail->next = L->head;        return 1;    }    Node * pos = L->head;    while (pos->next != node && pos != L->tail) {        pos = pos->next;    }    if (pos->next == node) {        if (node == L->tail) {            L->tail = pos;        }        pos->next = node->next;        return 1;    }    fprintf(stderr, "No such node in linked list.\n");    return 0;}//------------------------------------------------------------------------

測試可如下:

void test_for_circular_single_linked_list() {    CSLL * L = (CSLL*)malloc(sizeof(CSLL));    printf("%p\n", L->head);    item_t item = {10, NULL};    Node * node;    for (int i = 0; i < 10; i++) {        item.key = i + 10;        circular_single_linked_list_insert(L, item);    }    printf("CSLL head is in location:%p\n", L->head);    linked_list_traverse(L->head);    for (int i = -1; i <= 10; i++) {        item.key = i + 10;        node = circular_single_linked_list_search(L, item);        if (node != NULL)            printf("Node %d in location %p delete :%d\n", node->item.key, node, \                circular_single_linked_list_delete(L, node));        //linked_list_traverse(L->head);    }    printf("---------------------------------------------\n");    for (int i = 0; i < 10; i++) {        item.key = i + 10;        circular_single_linked_list_insert(L, item);    }    printf("CSLL head is in location:%p\n", L->head);    linked_list_traverse(L->head);    for (int i = 11; i >= -1; i--) {        item.key = i + 10;        node = circular_single_linked_list_search(L, item);        if (node != NULL)            printf("Node %d in location %p delete :%d\n", node->item.key, node, \                circular_single_linked_list_delete(L, node));    }    linked_list_free(L->head);    free(L);}

有哨兵的雙連結未排序迴圈鏈表可如如下實現:

//functions for cicular double linked list with sentinelCDLLS* circular_double_linked_list_with_sentinel_init() {    CDLLS * L = (CDLLS*)malloc(sizeof(CDLLS));    L->nil = (Node*)malloc(sizeof(Node));    L->nil->
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.