圖解算法與數據結構
1、前言
今天開始鏈表,這一講是單鏈表,下一講是雙鏈表。
下面一起來看看吧!!!
2、代碼
模板:
//C++單向鏈表模板
class MyListForward{
private:
struct ListNode{
int val;
ListNode *next;
ListNode(int x) :val(x), next(nullptr){}
};
ListNode* head;
public:
MyListForward() :head(nullptr){}
//獲得鏈表中第index個節點的值
int get(int index){
int i = 0;
ListNode *p = head;
while (p&&i<index){
p = p->next;
i++;
}
if (p)return p->val;
else return -1;
}
//在鏈表頭部插一個值爲val的節點
void addAtHead(int val){
ListNode *p = new ListNode(val);
p->next = head;
head = p;//更換頭節點
}
//在鏈表尾部添加一個值爲val的節點
void addAtTail(int val){
ListNode *p = new ListNode(val);
//鏈表爲空,直接將新節點作爲頭節點
if (head == nullptr){
head = p;
return;
}
ListNode *q = head;
//遍歷直到q的next節點爲空
while (q->next){
q = q->next;
}
q->next = p;
}
//在索引爲index的節點之前添加值爲val的節點
void addAtIndex(int index, int val){
ListNode *node = new ListNode(val);
//1、index小於等於0,直接在頭部插入節點
if (index <= 0){
//若index小於等於0,我們僅需要在頭節點前面插入新節點就行了
//注意這裏不能使用指針p,因爲p=node時,p所指向的地址發生了變化,head指向的地址沒有變化,所以我們這裏要使用指針head
node->next = head;
head = node;
return;
}
int i = 0;
ListNode *p = head;
//在索引爲index的節點之前插入新節點,我們需要找到它的前驅節點,然後插入在它的前驅節點後面
while (p&&i<index - 1){
p = p->next;
++i;
}
//2、p爲索引節點的前驅節點
if (p){
node->next = p->next;
p->next = node;
}
}
//刪除索引爲index的節點
void deleteAtIndex(int index){
//1、index爲0,我們直接刪除head節點
if (index == 0 && head != nullptr){
ListNode *del = head;
head = head->next;
delete del;
return;
}
int i = 0;
ListNode* p = head;
//刪除索引爲index的節點,我們需要找到它的前驅節點p,p->next爲需要刪除節點
while (p&&i<index - 1){
p = p->next;
i++;
}
//2、index超過鏈表範圍,刪除失敗
if (!p)return;
//3、index的位置合法,我們找到需要刪除的p->next節點
if (p->next){
ListNode *del = p->next;
p->next = del->next;
delete del;
}
}
int length(){
int i = 0;
ListNode *p = head;
while (p){
i++;
p = p->next;
}
return i;
}
};
3、正文
單鏈表中的每個結點不僅包含值,還包含鏈接到下一個結點的引用字段。通過這種方式,單鏈表將所有結點按順序組織起來。
首先初始化你的單鏈表:
val
是值,next
是指針。
如果想在給定的結點之後添加新值,分三種情況:
- 頭結點;
- 尾結點;
- 任意位置;
與數組不同,不需要將所有元素移動到插入元素之後。因此,可以在 O(1) 時間複雜度中將新結點插入到鏈表中,這非常高效。
如果想從單鏈表中刪除現有結點,分兩種情況:
- 頭結點;
- 任意位置;
刪除結點的時間複雜度將是 O(N)。空間複雜度爲 O(1),因爲只需要常量空間來存儲指針。
4、實例
LeetCode 707,一個設計鏈表的題。
代碼如上。
/**
* Your MyLinkedList object will be instantiated and called as such:
* MyLinkedList* obj = new MyLinkedList();
* int param_1 = obj->get(index);
* obj->addAtHead(val);
* obj->addAtTail(val);
* obj->addAtIndex(index,val);
* obj->deleteAtIndex(index);
*/
如果有幸幫到你,請幫我點個【贊】,給個【關注】!如果能順帶【評論】給個鼓勵,我將不勝感激。
如果想要更多的資源,歡迎關注 @我是管小亮,文字強迫症MAX~