【手繪漫畫】面試必考之手撕單鏈表(解題模板和深度剖析),(LeetCode 707)

在這裏插入圖片描述

圖解算法與數據結構

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~

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