資料結構學習之單向鏈表結構

來源:互聯網
上載者:User

註:本文的主要目的是為了記錄自己的學習過程,也方便與大家做交流。

轉載請註明來自: http://blog.csdn.net/ab198604/

最近突然間覺得應該補補IT技術的基礎的知識,因為對這些基礎知識的梳理不僅可以對自己所掌握的知識進一步鞏固,無論是提高自身的技術水平方面還是從後期就業方面,都是大有裨益的,所以還是要打好基礎,一步一個腳印才行,總之,知識需要有時間的積累。

從前自己並未系統的學習過電腦知識,對資料結構的認識也是一知半解,自從學了linux系統的一些知識之後,特別是發現在linux核心中對鏈表的運用隨處可見,由不得自己不重視,當然鏈表的運用範疇本身是非常廣泛的,如郵件清單、記憶體管理、多項式計算等,所以只要掌握了鏈表的基礎知識,就可以做到舉一反三了,對類似運用情境的鏈表代碼也就可以自然地掌握了。

鏈表其實有許多的種類:單向鏈表、雙向鏈表、單向迴圈鏈表和雙向迴圈鏈表。他們之間的複雜關係是逐步增加的,這裡主要介紹單向鏈表這種資料結構,因為它使用最為廣泛。

什麼是單向鏈表呢?

從字面上理解,那就是“單向”+“鏈表”,表明這種資料結構是有方向性的,並且只有一個方向。另外,“鏈表”表明這種資料結構是一種鏈式儲存結構,它不同於線性表的順序儲存結構。鏈表的相鄰元素在實體記憶體中不連續,所以這種結構可以充分利用一些系統的記憶體片段來完成一些事務,即如果採用鏈表結構有時可以解決當連續記憶體配置不足時的問題。既然是單向鏈表,那也意味著它是由各個元素之間通過一個指標彼此串連而組成的。每個元素包含兩部分:資料域和一個稱為next的指標域。通過採用這種結構,next的指標域將按某一個方向指向其下一個元素。最後一個元素的next指標域指向NULL,即為空白,它表示鏈表的末尾元素,鏈表的第一個元素稱為“頭”元素。鏈表的如下所示:


如所示,每個元素連結在一起形成一個鏈表。

單向鏈表的一個特性就是只能沿著next指標的方向尋找到其後續元素,如果要尋找到鏈表中的某個元素,只能從頭到尾遍曆整個鏈表。如果我們已經從頭到尾訪問到某個元素,但是此時又想訪問這個元素的前幾個元素,此時我們是無法進行訪問,因為在我們的元素中並沒有維護一個前向的連結,所以此時必須再次從頭進行遍曆操作才行。

簡單回顧完單向鏈表的基本知識點後,下面我們要真槍實彈的開練了。以下是具體的代碼,它包含三個部分,先對每個部分進行簡單的描述說明:

list.h -->主要是單向鏈表的一些介面定義

list.c -->主要是對介面定義的具體細節實現

main.c -->主要是展示鏈表的一些簡單應用


1 單鏈表的介面定義

/* * file name: list.h * author: zhm * date: 2012-12-06 */#ifndef LIST_H#define LIST_H#include <stdlib.h>/* define a struct for list element */typedef struct ListElmt_{    void *data;    struct ListElmt_ *next;}ListElmt;/* define a structure for linked list */typedef struct List_{    int size;    void (*match)(const void *key1, const void *key2);    void (*destroy)(void *data);    ListElmt *head;    ListElmt *tail;}List;/* define public interface */void list_init(List *list, void(*destroy)(void *data));void list_destroy(List *list);int list_ins_next(List *list, ListElmt *elemet, const void *data);int list_rem_next(List *list, ListElmt *element, void **data);#define list_size(list) ((list)->size)#define list_head(list) ((list)->head)#define list_tail(list) ((list)->tail)#define list_is_head(list, element) ((element) == (list)->head ? 1 : 0)#define list_is_tail(list, element) ((element) == (list)->tail ? 1 : 0)#define list_data(element) ((element)->data)#define list_next(element) ((element)->next)#endif

單向鏈表的操作主要有插入,刪除結點,初始化鏈表和刪除鏈表操作。

2 單鏈表的介面實現細節

/* * filename: list.c * author: zhm * date: 2012-12-06  */#include <stdlib.h>#include <string.h>#include "list.h"/* list_init */void list_init(List *list, void (*destroy)(void *data)){    list->size = 0;    list->destroy = destroy;    list->head = NULL;    list->tail = NULL;    return;}/* list_destroy */void list_destroy(List *list){    void *data; //keep the data in the element of the list    /*remove the element */    while( list_size(list) > 0 )     {        if(list_rem_next(list, NULL, (void **)&data) == 0 &&                 list->destroy != NULL)        {            list->destroy(data);        }    }    memset(list, 0, sizeof(list));    return;}/* list_ins_next */int list_ins_next(List *list, ListElmt *element, const void *data){    /* Allocate storage */    ListElmt *new_element = NULL;    new_element = (ListElmt *)malloc(sizeof(ListElmt));    if( new_element == NULL )        return -1;    new_element->data = (void *)data;    /* Insert the element into the list */    if( element == NULL ) //from head position to insert    {        if( list_size(list) == 0 )  //be care to tail            list->tail = new_element;        new_element->next = list->head;        list->head = new_element;    }    else    {        if( element->next == NULL ) //be care to tail            list->tail = new_element;        new_element->next = element->next;        element->next = new_element;    }    /*Adjust size */    list->size++;    return 0;}/* list_rem_next */int list_rem_next(List *list, ListElmt *element, void **data){    ListElmt *old_element;    //if the list is empty    if( list_size(list) == 0 )        return -1;    /* Remove the element from the list */    if( element == NULL ) //from head to remove    {        *data = list->head->data; //keep the data.        old_element = list->head;        list->head = list->head->next;        if( list_size(list) == 1 )  //be care to the tail            list->tail = NULL;    }    else    {        //if the element to be removed is NULL        if( element->next == NULL )            return -1;        *data = element->next->data;        old_element = element->next;        element->next = element->next->next;        if( element->next == NULL ) //be care to the tail            list->tail = element;    }    //free the memory    free(old_element);    list->size--;    return 0;}

3 測試案例代碼,如下所示:

/* * filename: main.c * author:zhm * date: 2012-12-06 */#include <string.h>#include <stdlib.h>#include <stdio.h>#include "list.h"/* destroy */void destroy(void *data){    printf("in destroy\n");    free(data);    return;}/* main */int main(int argc, char **argv){    ListElmt *elem_ptr = NULL;    int i;    int ret;    int *data = NULL;    /* Create a linked list */    List list_exp;    /* init the list */    printf("\ninit the list:\n");    list_init(&list_exp, destroy);     /* insert the element */    printf("\ncreate a list:\n");    for(i = 0; i < 10; i++ )    {        data = (int *)malloc(sizeof(int));        if( data == NULL )            return -1;        *data = i;        list_ins_next(&list_exp, NULL, (void *)data);    }    /* now the list has 10 element, then traverse and print every element */    elem_ptr = list_exp.head;    for( i = 0; i < 10; i++ )    {        printf("%d ",  *(int *)list_data(elem_ptr) );        elem_ptr = list_next(elem_ptr);    }    printf("\n");    /* Remove the element, its value of the data equal 4,then traverse and print again */    elem_ptr = list_exp.head;    for( i = 0; i < list_size(&list_exp); i++ )    {        if( *(int *)list_data(elem_ptr) == 5 )        {            ret = list_rem_next(&list_exp, elem_ptr, (void **)&data);            if( ret == 0 )            {                destroy(data);            }        }        elem_ptr = list_next(elem_ptr);    }    printf("after remove the element: value = 4\n");    //traverse and print again    elem_ptr = list_exp.head;    for( i = 0; i <list_size(&list_exp); i++ )    {        printf("%d ",  *(int *)list_data(elem_ptr) );        elem_ptr = list_next(elem_ptr);    }    printf("\n\n");    printf("here begin to destroy the list :\n");    //destroy the linked list    list_destroy(&list_exp);    return 0;}

4 顯示執行結果,如:


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.