1. 程式人生 > >實現你的第一個鏈表——手把手教你創建單向鏈表

實現你的第一個鏈表——手把手教你創建單向鏈表

linked 中一 語句 c語言實現 create 結點之間 現在 引入 什麽

寫在前面

這是我原發在獨立博客上的文章,用來幫助初學鏈表的同學們理解鏈表,現在發在這裏供大家批評。

為什麽要使用鏈表?

這是我們首先要考慮的一個問題,我們之前已經學過了數組的使用,可以方便快速地存儲大量數據,為何還要引入“鏈表”的概念呢?

比如我們讓50個小朋友排排坐,那事情是很好辦的:只需要準備50個椅子,讓小朋友們依次坐好即可,這就是數組的使用。但是,如果我們預先不知道有多少小朋友,那事情就不好辦了,我們可能需要準備大量的椅子,但這就會浪費很多空間;此外,如果一個新來的小朋友必須進入特定兩人之間,椅子是靜態的,只能讓後面的人一個一個依次往後挪,他才能坐到這個位置,這無疑十分浪費時間。

因此,在這種情況下,我們不再讓小朋友排排坐,而是讓每人拉著另一個人的衣襟,這樣不需要確定椅子數,如果有人需要插入,也只需改變一兩個人拉誰的衣襟即可。這也就是我們所說的鏈表。(要註意,這裏是“拉衣襟”而不是“手拉手”,因此嚴格地說是一種單向鏈表)

C語言實現

實現方式的選擇

我們現在已經知道,要實現鏈表,我們需要有數據(小朋友),又要把數據連起來(拉衣襟),在編程中,我們特別需要考慮對“拉衣襟”的實現,這時,C語言中的指針就為我們提供了絕佳的工具,因為它可以指向其他的元素。為了將數據和指針組合起來,我們需要一個結構體,在鏈表中,我們將這種數據域指針域的組合稱為結點(node)。

在這裏的例子中,為了簡單,我們在每個結點只存儲一個整型變量:

typedef struct linked_list {
    int num;
    struct linked_list* next;
} l;

在這個結點中,數據域為整型變量num,指針域為指針next,用來指向下一個結點,結點之間依次相連,從而實現“拉衣襟”的操作。

創建結點

創建頭結點

很多時候,我們都需要先創建一個不存儲數據的頭結點,這樣即使遇到空鏈表或對第一個元素的操作等情況也不會出現問題。(註:在課本示例中,並沒有使用頭結點,但我認為最好使用)

特別註意下面幾個名詞的區別!

  • 頭結點:一個空結點,位於單向鏈表最前面,它的指針域指向第一個有數據的結點
  • 尾結點:最後一個結點,它的指針域最終指向NULL
  • 頭指針:指向頭結點的指針,在訪問單向鏈表時要從這個指針所指的結點開始
  • 尾指針:指向尾結點的指針,用於創建鏈表過程中的操作
l * head, * new_node, * tail; //聲明頭指針、創建新結點所用指針、尾指針
head = (l*)malloc(sizeof(l)); //為頭結點分配內存
tail = head; //讓尾指針指向頭指針

創建數據結點

接下來我們就可以創建有數據的結點內容了!下面先以其中一個結點為例:

new_node = (l*)malloc(sizeof(l)); //為結點分配內存
scanf("%d", &new_node->num); //輸入數據
tail->next = new_node; //讓尾結點的指針域指向新創建的結點
tail = new_node; //讓尾指針指向新的結點

當然,在實際中,肯定不會只創建一個數據結點,而是用循環語句創建完所需的所有結點。

結束鏈表創建

現在,我們假設所有結點創建完畢,需要進行最後一步——將尾結點的指針域指向NULL,這樣就可以標記鏈表的結束。

tail->next = NULL;

創建鏈表的整體操作

#include<cstdio>
#include<cstdlib>

//使用結構體構建結點
typedef struct linked_list {
    int num;
    struct linked_list* next;
} l;

l* create(int n) {
    l * head, * new_node, * tail;
    int i = 0;
    //創建頭結點
    head = (l*)malloc(sizeof(l));
    tail = head;
    //使用循環,創建n個數據結點
    for(i=0; i<n; ++i) {
        new_node = (l*)malloc(sizeof(l));
        scanf("%d", &new_node->num);
        tail->next = new_node;
        tail = new_node;
    }
    //將尾結點的指針域指向NULL,標誌鏈表結束
    tail->next = NULL;
    //返回頭指針
    return head;
}

int main() {
    l* head_pointer;
    int n;
    printf("請輸入數據個數:");
    scanf("%d", &n);
    printf("請依次輸入數據:");
    head_pointer = create(n);
    /*
    下面可以進行鏈表操作,本文暫不演示
    */
    return 0;
}

要註意,我們需要在最後讓函數返回頭指針,以便在主函數中通過頭指針訪問我們所創建的鏈表。

總結

本文一步步介紹了創建一個鏈表的方法,由於我寫了半天,現在有點犯懶了,欲知鏈表的訪問、修改等操作,且聽下回分解……

實現你的第一個鏈表——手把手教你創建單向鏈表