1. 程式人生 > >單鏈表不帶頭標準c語言實現

單鏈表不帶頭標準c語言實現

連結串列是一種物理儲存單元上非連續、非順序的儲存結構資料元素的邏輯順序是通過連結串列中的指標連結次序實現的。連結串列由一系列結點(連結串列中每一個元素稱為結點)組成,結點可以在執行時動態生成。每個結點包括兩個部分:一個是儲存資料元素的資料域,另一個是儲存下一個結點地址的指標域。 相比於線性表順序結構,操作複雜。由於不必須按順序儲存,連結串列在插入的時候可以達到O(1)的複雜度,比另一種線性表順序錶快得多,但是查詢一個節點或者訪問特定編號的節點則需要O(n)的時間,而線性表和順序表相應的時間複雜度分別是O(logn)和O(1)。

使用連結串列結構可以克服陣列連結串列需要預先知道資料大小的缺點,連結串列結構可以充分利用計算機記憶體空間,實現靈活的記憶體動態管理。但是連結串列失去了

陣列隨機讀取的優點,同時連結串列由於增加了結點的指標域,空間開銷比較大。連結串列最明顯的好處就是,常規陣列排列關聯專案的方式可能不同於這些資料專案在記憶體磁碟上順序,資料的存取往往要在不同的排列順序中轉換。連結串列允許插入和移除表上任意位置上的節點,但是不允許隨機存取。連結串列有很多種不同的型別:單向連結串列雙向連結串列以及迴圈連結串列

下面給出不帶頭的單鏈表標準實現:

定義節點:

typedef struct node 
{ 
    int data;
    struct node * next;
}Node;

尾插:

void pushBackList(Node ** list, int data) 
{ 
    Node * head = *list;
    Node * newNode = (Node *)malloc(sizeof(Node));//申請空間
    newNode->data = data; newNode->next = NULL;
    if(*list == NULL)//為空
        *list = newNode;
    else//非空
    {
        while(head ->next != NULL)
            head = head->next;
        head->next = newNode;
    }
}

插入:

int insertList(Node ** list, int index, int data) 
{
    int n;
    int size = sizeList(*list); 
    Node * head = *list; 
    Node * newNode, * temp;
    if(index<0 || index>size) return 0;//非法
    newNode = (Node *)malloc(sizeof(Node)); //建立新節點
    newNode->data = data; 
    newNode->next = NULL;
    if(index == 0) //頭插
    {
        newNode->next = head; 
        *list = newNode; 
        return 1; 
    }
    for(n=1; n<index; n++) //非頭插
        head = head->next;
    if(index != size) 
        newNode->next = head->next; 
    //連結串列尾部next不需指定
    head->next = newNode; 
    return 1;
}

按值刪除:

void deleteList(Node ** list, int data) 
{ 
    Node * head = *list; Node * temp; 
    while(head->next!=NULL) 
    { 
        if(head->next->data != data) 
        { 
            head=head->next; 
            continue; 
        } 
        temp = head->next;
        if(head->next->next == NULL) //尾節點刪除
            head->next = NULL; 
        else 
            head->next = temp->next; 
        free(temp);
    }    
    head = *list; 
    if(head->data == data) //頭結點刪除
    { 
        temp = head; 
        *list = head->next; 
        head = head->next; 
        free(temp); 
    }
}

列印:

void printList(Node * head) 
{ 
    Node * temp = head; 
    for(; temp != NULL; temp=temp->next) 
        printf("%d ", temp->data); 
    printf("\n"); 
}

清空:

void freeList(Node ** list) 
{ 
    Node * head = *list; 
    Node * temp = NULL; 
    while(head != NULL) //依次釋放
    { 
        temp = head; 
        head = head->next; 
        free(temp); 
    } 
    *list = NULL; //置空
}

別的也沒啥了,都是基本操作

有些程式碼要分情況,很麻煩,可讀性較強吧