1. 程式人生 > >【程式設計2】單鏈表+單鏈表反轉(LeetCode. 206)

【程式設計2】單鏈表+單鏈表反轉(LeetCode. 206)

文章目錄

一、連結串列

連結串列:不需要一塊連續的記憶體空間,它通過“指標”將一組零散的記憶體塊串聯起來使用.
記憶體分佈
在這裡插入圖片描述
最常用的連結串列結構:單鏈表、雙向連結串列和迴圈連結串列

二、單鏈表

1、基本概念

(1)單鏈表

當一個序列中只含有指向它的後繼結點的連結時,就稱該連結串列為單鏈表。

  • 非空表(有頭結點):
    在這裡插入圖片描述
  • 空表:
    在這裡插入圖片描述

(2)頭指標——必有元素

連結串列指向第一個結點的指標,若連結串列有頭結點,則是指向頭結點的指標。頭指標具有標識作用。

任何情況下,頭指標都存在,無論連結串列是否為空

(3)頭結點——非必需元素

為了操作的統一和方便(插入/刪除首元結點)設立的,放在首元結點(第一元素結點)之前,其資料域一般無意義(也可以 存放連結串列的長度)。

(4)尾結點

最後一個結點指標為“空”(通常用NULL或“^”符號表示),是連結串列的結束標誌,表示它沒有後繼結點。

2、查詢操作

目標:隨機訪問第 k 個元素
==》依次遍歷連結串列,查詢第 k 個元素
==》時間複雜度:O(n)

3、插入操作

目標:插入 x 結點
==》時間複雜度:O(1)
x->next = a2->next
a2->next = x
在這裡插入圖片描述

4、刪除操作

目標:刪除 a2 結點
==》時間複雜度:O(1)
p = a1 -> next
a1->next = p->next
在這裡插入圖片描述

三、設計思想—— 時間 <-> 空間

  • 當記憶體足夠時,若追求程式碼的執行速度 ==》選擇空間複雜度高、時間複雜度相對較低的演算法或者資料結構
  • 當記憶體比較緊張 ==》時間換空間

四、LeetCode206.反轉連結串列

1、題目描述

反轉一個單鏈表。

2、示例

輸入: 1->2->3->4->5->NULL
輸出: 5->4->3->2->1->NULL

3、分析

  • 要實現單鏈表反轉,主要是修改結點的指標:將當前結點的指標指向其前驅結點。
  • 在反轉的過程中為了防止斷鏈,需要記錄下一結點的資訊。例如:假設 i 結點之前,我們把所有的結點的指標都已經反轉了,那麼自然 i 和以後的結點連結發生了斷裂!
    在這裡插入圖片描述

==》利用三個指標,分別記錄:當前結點、其前驅結點、其後繼結點即可實現連結串列反轉。

4、實現

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {        
        ListNode *pre = NULL;
        ListNode *pcur = head;
        ListNode *pnext = NULL;
        ListNode *tail = NULL;
        
        while(pcur != NULL){
            pnext = pcur->next;
            if(pnext == NULL)
                tail = pcur;
                
            pcur->next = pre;
            
            pre =pcur;
            pcur = pnext;
        }
        return tail;
    }
};

==》時間複雜度:O(n)

五、碎碎念

  • 很基本的題目,但是自己實現起來還是有困難,還得多多實踐和思考;
  • 把連結串列的操作理解實現。
  • 後續加上leetcode92