1、單鏈表的讀取
算法思路:
(1) 聲明一個結點 p 指向鏈表第一個結點(這裏是存儲數據的第一個節點,不是頭結點),初始化 j 從 1 開始;
(2) 當 j < i 時,就遍歷鏈表,讓 p 的指針向後移動,不斷指向下一結點, j 累加 1;
(3) 若到鏈表末尾 p 爲空,則說明第 i 個元素不存在;
(4) 否則查找成功,返回結點 p 的數據 。
代碼:
Status GetElem(LinkList *L, int i, ElemType *e)
{
LinkList p;
p = (*L)->next;
int j = 1;
while (p&&j < i)
{
p = p->next;
j++;
}
if (!p || j>i)/*貌似出現不了j>i的情況。。。;超出範圍時,p=NUll*/
return ERROR;
*e = p->data;
return OK;
}
注:由於單鏈表的結構中沒有定義表長,所以不能事先知道要循環多少次,因此也就不方便使用 for 來控制循環。其主要核心思想就是 “工作指針後移’ ,這其實也是很多算法的常用技術。
2、單鏈表的插入
算法思路:
(1) 聲明一結點 p 指向鏈表第一個結點(這裏是頭結點),初始化 j 從 1 開始;
(2) 當 j < i 時,就遍歷鏈表,讓 p 的指針向後移動,不斷指向下一結點, j 累加 1;
(3) 若到鏈表末尾 p 爲空,則說明第 i 個元素不存在;
(4) 否則查找成功,在系統中生成一個空結點 s;
(5) 將數據元素 e 賦值給 s->data ;
(6) 單鏈表的插入標準語旬 s->next=p->next; p->next=s ;
(7) 返回成功 。
邏輯圖:
代碼:
Status ListInsert(LinkList *L, int i, ElemType e)
{
int j=1;
LinkList p,s;
p = (*L);/*頭結點*/
while (p&&j < i)
{
p = p->next;
j++;
}
if (!p->next||j>i)
return ERROR;
s = (LinkList)malloc(sizeof(Node));/*因爲s是插入的新節點,所以要爲它分配內存空間,區別於
其他函數的臨時節點,臨時節點不需要分配空間*/
s->data=e;
s->next = p->next;
p->next = s;
return OK;
}
3、單鏈表的刪除
算法思路:
- 聲明一結點 p 指 向鏈表第一個結點 , 初始化 j 從 1 開始;
- 當j < i時,就遍歷鏈表, 讓 p 的指針向後移動,不斷指向下一個結點,j累加1;
- 若到鏈表末尾 p 爲空,則說明第 i 個元素不存在;
4 . 否則查找成功,將欲刪除的結點 p-> next 賦值給 q ;
5 . 單鏈表的刪除標準語句 p->next=q->next;
6 . 將 q 結點中的數據賦值給 e, 作爲返回;
7 . 釋放 q 結點;
8 . 返回成功。
邏輯圖:
代碼:
Status ListDelete(LinkList *L, int i, ElemType *e)
{
LinkList p,s;
p = (*L);/*頭結點*/
int j=1;
/*因爲p爲要刪除節點的前一節點,所以需要用p->next判斷是否超出鏈表範圍*/
while (p->next&&j < i)
{
p = p->next;
j++;
}
if (!(p->next) || j>i)
return ERROR;
//s = (LinkList)malloc(sizeof(Node));/*臨時節點,不需要分配內存*/
s = p->next;
*e = s->data;
p->next = s->next;
free(s);
return OK;
}
4、單鏈表結構與順序存儲結構優缺點