之前只用python寫過鏈表


並不一定要動態分配鴨~

#include &

struct node {
char payload;
struct node *next;
};

int main()
{
struct node node_c = {C, NULL};
struct node node_b = {B, node_c};
struct node node_a = {A, node_b};

struct node *linked_list = node_a;

for (struct node *p = linked_list; p != NULL; p = p-&>next) {
printf("%c -&> ", p-&>payload);
}
puts("[END]");
}

這樣也是一個鏈表,節點都在棧上。不過這樣的鏈表需要編譯期已知所有節點,沒啥大用。

所以邏輯是這樣的:

  • 我要實現鏈表,並且這個鏈表要支持動態改變長度
  • 所以節點必須是動態分配出來的
  • 這個鏈表要給別人用的,而不是我在一個函數裏搭起來自娛自樂
  • 所以這個鏈表節點不能分配在棧上,必須在堆上(比如使用 malloc)

其實就是高中數學「充要條件」,順過來推是 OK 的,但不能反過來說只要在 C 裏實現鏈表,就必須動態分配,甚至必須用 malloc 來動態分配。


C的一般變數都是在棧上分配的,函數退出就沒有了,你應該不希望退出當前函數,這個節點就消失了吧?

malloc動態分配的變數是在堆上的,只要不free就一直存在。

也可以通過全局數組的方式一次性創建多個節點,只要程序不退出就會一直存在,但是這種方式是有上限的。


既然用Python寫過鏈表應該懂得它的底層原理是基於C語言的,你單單會使用什麼list

,dict,map但是不知道內存怎麼分配的不能稱之為寫過鏈表,你這是會使用這些內置函數完成鏈表的基本操作。


用靜態數組一樣可以做鏈表,鏈表的指針不一定就非要放內存地址,數組下標一樣可以當指針。

int node[4] = { 1, 2, 3, 4 };
int next[4] = { 4, 0, 2, 3 };
int head = 0 ;

這也是鏈表。


因為節點的數量不確定。如果能確定最大數量,那是可以在靜態區提前預先劃分的,比如早期遊戲裏的子彈和敵人。


先問是不是,再問為什麼。

壓根不成立的事情沒什麼為什麼


先要弄清鏈表的使用場景一般都是什麼。不動態分配內存,你說還有使用鏈表的意義嗎?直接數組不就完了


因為一般這個鏈表節點分配以後要跨越他的生命週期作用域,所以一般都用malloc。


推薦閱讀:
相關文章