資料結構之單鏈表

2021-09-20 10:09:52 字數 3968 閱讀 8293

1. 熟悉什麼是鍊錶,鍊錶的分類?

鍊錶是一種物理儲存結構上非連續,非順序的儲存結構,資料元素的邏輯順序是通過鍊錶中的指標鏈結次序實現的。

鍊錶一共分為8種。1.單向、雙向。2.帶頭、不帶頭。3.迴圈、不迴圈。由這幾種情況組合而成。

常見的是不帶頭非迴圈單鏈表、帶頭迴圈雙向鍊錶。

2. 熟悉鍊錶帶頭結點和不帶頭結點的區別?頭指標:通常使用「頭指標」來標識乙個鍊錶,如單鏈表l,頭指標為null的時表示乙個空鍊錶。

頭結點:在單鏈表的第乙個結點之前附加乙個結點,稱為頭結點。頭結點的data域可以不設任何資訊,也可以記錄表長等相關資訊。

[注意]無論是否有頭結點,頭指標始終指向鍊錶的第乙個結點。如果有頭結點,頭指標就指向頭結點。

引入頭結點的優勢

鍊錶可以沒有頭結點,但是必須要有頭指標,因為要用頭指標來標識乙個鍊錶。設煉表的頭指標為phead。除了頭結點之外,還需要乙個指向鍊錶一般元素的指標pnode(因為phead只能指向表頭,不能指向其他元素,故需要另設指標)。

優勢1:第1個位置的插入刪除更加方便

若使用頭結點,則第1個位置的插入和刪除都是對p—>next進行操作,而不用動p本身,而且減少了演算法分支(即if else分支)具體的流程為:

插入操作如下

1.p指向要插入結點的前驅結點,若要插入的結點為第1個位置,則其前驅結點就是頭結點,此時p指向頭結點。

2.讓新結點s的next指向p的next,即s—>next = p—>next;

3.讓p—>next指向s,即p—>next = s;

刪除操作如下

1.p指向要刪除結點的前驅結點,若要刪除的結點為第1個位置,則其前驅結點就是頭結點,此時p指向頭結點。

2.讓臨時指標q指向要刪除的結點,即q = p—>next;

3.讓p的next指向要刪除結點的下乙個結點,即p—>next = q—>next;

4.釋放q的空間,即free(q);

若沒有頭結點,在第1個位置插入或刪除時,需要動頭指標。

插入操作如下

1.判斷要插入的是否是第1個位置,若是需要特殊處理。

2.若是第1個位置,讓新結點s的next指向頭指標ptrl。

3.return s,此時s作為鍊錶的頭指標。此時的更新了鍊錶的頭指標。

4.若不是第1個位置,首先找到要插入結點的前驅結點,讓p指向這個前驅結點。

5.讓新結點s的next指向p的next,即s—>next = p—>next;

6.讓p—>next指向s,即p—>next = s;

7.return ptrl,此時ptrl還是作為鍊錶的頭指標,沒有被修改,但考慮到一致性需要這樣寫。

刪除操作如下

1.判斷要刪除的是否是第1個位置,若是需要特殊處理。

2.若是第1個位置,讓s指向要刪除的結點。首先判斷ptrl是否為空,若是直接return null;若不為空,則將鍊錶的頭結點挪到下乙個位置,即ptrl = ptrl—>next;

3.free(s);然後return ptrl

4.若不是第1個位置,首先找到要刪除結點的前驅結點,讓p指向這個前驅結點。

5.讓臨時指標q指向要刪除的結點,即q = p—>next;

6.讓p的next指向要刪除結點的下乙個結點,即p—>next = q—>next;

7.釋放q的空間,即free(q);

8.return ptrl

優勢2:統一空表和非空表的處理

若使用頭結點,無論表是否為空,頭指標都指向頭結點,也就是*lnode型別,對於空表和非空表的操作是一致的。

若不使用頭結點,當表非空時,頭指標指向第1個結點的位址,即*lnode型別,但是對於空表,頭指標指向的是null,此時空表和非空表的操作是不一致的。

3.單鏈表操作

typedef int sdatatype; 

// 鍊錶的節點

typedef struct slistnode

node, *pnode;

// 鍊錶的結構,給乙個頭指標儲存鍊錶第乙個節點的位址

typedef struct slist

slist, *pslist;

// 鍊錶的初始化

void slistinit(slist* s);

void slistinit(slist* s, sdatatype data)

// 在鍊錶s最後乙個節點後插入值為data的節點

void slistpushback(slist* s, sdatatype data);

void slistpushback(slist* s, sdatatype data)

else

}// 刪除鍊錶s最後乙個節點

void slistpopback(slist* s);

void slistpopback(slist* s)

else if (null == s->_phead->_pnext)

else

free(pcur);

pcur->_pnext = null; }}

// 在鍊錶s第乙個節點前插入值為data的節點

void slistpushfront(slist* s, sdatatype data);

void slistpushfront(slist* s, sdatatype data)

// 刪除鍊錶s的第乙個節點

void slistpopfront(slist* s);

void slistpopfront(slist* s)

// 在鍊錶的pos位置後插入值為data的節點

void slistinsert(pnode pos, sdatatype data);

void slistinsert(pnode pos, sdatatype data)

pnewnode = buyslistnode(data);

pnewnode->_pnext = pos->_pnext;

pos->_pnext = pnewnode;

}// 刪除鍊錶s中pos位置的節點

void slisterase(slist* s, pnode pos);

void slisterase(slist* s, pnode pos)

if (pos == s->_phead)

else

if (pprepos)

} free(pos);

}// 在鍊錶中查詢值為data的節點,找到返回該節點的位址,否則返回null

pnode slistfind(slist* s, sdatatype data);

void slistfind(slist* s, sdatatype data)

pcur = pcur->_pnext;

} return null;

}// 獲取鍊錶中有效節點的個數

size_t slistsize(slist* s);

int slistsize(slist* s)

return count;

}// 檢測鍊錶是否為空

int slistempty(slist* s);

int slistempty(slist* s)

// 將鍊錶中有效節點清空

void slistclear(slist* s);

void slistclear(slist* s)

pcur == null;

}// 銷毀鍊錶

void slistdestroy(slist* s);

void slistdestroy(slist* s)

資料結構之單鏈表

date 08 07 06 descript 單鏈表的實現與應用 public class linlist public node gethead 定位函式 public void index int i throws exception if i 1 current head.next int j...

資料結構之單鏈表

鍊錶 儲存結構的一種,包含兩個部分,資料域和指標域,相對於順序儲存結構來說,插入和刪除的演算法時間複雜度只為o 1 定義 定義 typedef struct node linklist linklist,指標指向每乙個元素 typedef struct nodenode 以下為簡單的c語言實現 in...

資料結構之單鏈表

由於順序表再插入或者刪除時需要移動大量資料,並且如果表比較大,會比較難分配連續的儲存空間導致儲存資料失敗。因此可以採用鍊錶結構,鍊錶結構是一種動態儲存分配的結構形式,可以根據需要動態的申請所需的儲存單元。鍊錶又分為單鏈表,雙向鍊錶,以及單迴圈鍊錶,多重鏈的迴圈鍊錶。本文先介紹單鏈表。典型的單鏈表結構...