3.2.2 單鏈表的讀取、插入和刪除

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、單鏈表的刪除
算法思路:

  1. 聲明一結點 p 指 向鏈表第一個結點 , 初始化 j 從 1 開始;
  2. 當j < i時,就遍歷鏈表, 讓 p 的指針向後移動,不斷指向下一個結點,j累加1;
  3. 若到鏈表末尾 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、單鏈表結構與順序存儲結構優缺點
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章