1. 程式人生 > >第三節、大秦帝國的連坐與鏈表(一)

第三節、大秦帝國的連坐與鏈表(一)

算法基礎 鏈表 單向鏈表

1、大秦帝國的連坐

孫皓暉先生在《大秦帝國(第一部)》中講到:

烈酒下喉,衛鞅精神為之一振,“《治秦九論》乃衛鞅謀劃的變法大綱。其一《田論》,立定廢井田、開阡陌、田得買賣之法令……其五《郡縣論》,將秦國舊世族的自治封地一律取締,設郡縣兩級官府,直轄於國府之下,使全國治權一統,如臂使指。其六《連坐論》,縣下設裏、村、甲三級小吏。民以十戶為一甲,一人犯罪,十戶連坐,使民眾怯於私鬥犯罪而勇於公戰立功。”

技術分享圖片

連坐制就是一條隱形的繩子,把“鄉裏鄉親”們串聯起來。

(連坐制確實在特定的歷史條件下發揮了巨大的作用,之後一系列的制度安排又將大秦帝國拖入了深淵。)

連坐制本身就像一個鏈表(Linked list ),一個個的人串聯起來,形成一種獨特的結構。

2、鏈表的由來和表示

存儲數據的時候我們通常用的是數組,數組最大的特點就是可以通過下標快速查找,也就是便於檢索。

但對於線性表(數組和鏈表都屬於線性表)常見的插入操作,數組就有些力不從心了。

技術分享圖片

為了在數組中插入一個數據,需要移動後面所有的數據!

鏈表正是為了快速插入的問題。

鏈表每一個節點都由數據域指向下一個節點的指針構成;
多個節點首尾相連,構成線性表。

技術分享圖片

上一節《第二節、算法中的公平——隊列》我們講到了結構體,忘記結構體的定義的同學可以出門左轉,查看上一節。

這裏,我們就使用結構體表示鏈表,struct list_node就是鏈表的一個節點,包含一個數據域和一個指向下一個節點的指針。

typedef struct list_node  {  
    int data ; //數據域,用於存儲數據  
    struct list_node *next ; //指向下一個節點的指針
}single_list;  

這裏的struct list_node的用法與上一節的不同,使用typedef,大括號後面也有single_list。

這樣以後在定義struct list_node變量的時候就不用寫一大長串了,直接single_list就可以了。

//下面兩種方式等價
struct list_node node;
single_list node;

3、鏈表的基本用法

與此同時,為了實現便於插入數據

的要求,鏈表的長度必須是可變的,否則可能沒有空間插入!

所以,鏈表的初始化以及插入操作需要申請存儲空間,函數為malloc()函數,用來分配存儲空間。對應的有釋放存儲空間,使用free()函數。

由於項目運行結束後會自動回收存儲空間,所以對於小項目而言,可以不手動回收,有興趣可以搜索free()函數的用法。

下面的代碼生成了一個最開始的一個節點,數據data存儲的是5,因為接下來沒有數據,所以next指針指向空NULL。

#include <stdlib.h>  //malloc函數需要使用這個頭文件
single_list *node = NULL;          //1、定義頭指針
node = (single_list *)malloc(sizeof(single_list)); //2、分配內存空間  
node->data = 5;                   //3、給鏈表節點的數據賦值  
node->next = NULL;                 //4、將鏈表的指針域指向空  

技術分享圖片

我們可以printf打印數據,查看結果。

完整代碼:

/*
輸出:5
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>  
typedef struct list_node
{
    int data;
    struct list_node *next;
}single_list;
int main()
{
    single_list *node = NULL;          //1、定義一個頭指針  
    node = (single_list *)malloc(sizeof(single_list)); //2、分配內存空間  
    node->data = 5;                   //3、給鏈表節點的數據賦值  
    node->next = NULL;                 //4、將鏈表的指針域指向空  
    printf("%d\n", node->data);

    getchar();getchar();
    return 0;
}

這裏我們使用了->這個運算符,叫做結構體指針運算符,用來表示結構體內部的指針指向空間存儲的數據,比較拗口,看個例子就知道了。

//兩者等價,省了個括號!程序員都是偷懶的!
node->data = 5;
(*node).data=5;

4、小結

這一小節介紹的新知識比較多,吃多了難以消化,所以就不介紹更多了。簡單回顧下:

  • 鏈表,就是節點連在一起
  • 每一個節點包含一個數據域指向下一個節點的指針
  • 鏈表最大的好處是插入數據快
  • 為了實現插入數據快的功能,鏈表長度可變,要手動分配空間

鏈表的插入、刪除、遍歷操作,我們下一節再見!

第三節、大秦帝國的連坐與鏈表(一)