IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 代码随想录算法训练营三期 day 03 - 链表(1) -> 正文阅读

[数据结构与算法]代码随想录算法训练营三期 day 03 - 链表(1)

链表理论基础

原文链接:关于链表,你该了解这些!
定义:链表是一种用指针串联起来的数据结构,每个结点由两部分组成,数据域 v a l val val 和 指针域 n e x t next next。最后一个结点的指针域为 n u l l null null

struct ListNode {
	int val;
	ListNode *next;
	ListNode(int x): val(x), next(NULL) {};
};

类型:单链表、双链表(每个结点有两个指针域)、循环链表(首尾相接
存储方式:通过指针链接,内存地址不是连续的。
操作:
(1) 删除结点:
请添加图片描述
(1) 插入结点:
请添加图片描述
链表的插入和删除操作都是 O ( 1 ) O(1) O(1) 的复杂度,而且也不会影响其他结点。
但是对于单链表来说,删除最后一个结点,需要从头节点找到倒数第 2 2 2 个结点的 n e x t next next 指针进行操作,复杂度是 O ( n ) O(n) O(n)
链表和数组对比:

查询插入/删除适用场景
数组 O ( 1 ) O(1) O(1) O ( n ) O(n) O(n)数据量固定, 频繁查询,较少增删
链表 O ( n ) O(n) O(n) O ( 1 ) O(1) O(1)数据量固定,频繁增删, 较少查询

203. 移除链表元素

原文链接:203. 移除链表元素
题目链接:203. 移除链表元素
视频链接:链表基础操作| LeetCode:203.移除链表元素
学习记录:
(1) 不添加虚拟头节点:
删除 头结点 与 删除 其他结点 操作方式不一致:
i. 删除头结点: h e a d = h e a d → n e x t ; head = head \to next; head=headnext;(注意要使用 w h i l e while while)
ii. 删除其他结点: c u r → n e x t = c u r → n e x t → n e x t ; cur \to next = cur \to next \to next; curnext=curnextnext;
代码如下:

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        while (head != NULL && head -> val == val) {
            ListNode* tmp = head;
            head = head -> next;
            delete tmp;
        }
        ListNode* cur = head;
        while (cur != NULL && cur -> next != NULL) {
            if (cur -> next -> val == val) {
                ListNode* tmp = cur -> next;
                cur -> next = cur -> next -> next;
                delete tmp;
            } else {
                cur = cur -> next;
            }
        }
        return head;
    }
};

(2) 添加虚拟头节点
删除头结点与删除其他结点方式一致:
请添加图片描述
注意最后要返回的是 r e s = d u m m y H e a d → n e x t ; res = dummyHead \to next; res=dummyHeadnext;

class Solution {
public:
    ListNode* removeElements(ListNode* head, int val) {
        ListNode* dummyHead = new ListNode(0);
        dummyHead -> next = head;
        ListNode* cur = dummyHead;
        while (cur -> next != NULL) {
            if (cur -> next -> val == val) {
                ListNode* tmp = cur -> next;
                cur -> next = cur -> next -> next;
                delete tmp;
            } else {
                cur = cur -> next;
            }
        }
        ListNode* res = dummyHead -> next;
        delete dummyHead;
        return res;
    }
};

707. 设计链表

原文链接:707. 设计链表
题目链接:707. 设计链表
视频链接:帮你把链表操作学个通透!LeetCode:707. 设计链表
学习记录:
(1) 获取第 i n d e x index index 个结点的数值:
因为要找的是 第 i n d e x index index 个结点, 所以 c u r = d u m m y H e a d → n e x t ; cur = dummyHead \to next; cur=dummyHeadnext;

    int get(int index) {
        if (index >= size || index < 0) {
            return -1;
        }
        Node* cur = dummyHead -> next;
        while (index--) {
            cur = cur -> next;
        }
        return cur -> val;
    }

(2) 头插:
i. n e w N o d e → n e x t = d u m m y H e a d → n e x t ; newNode \to next = dummyHead \to next; newNodenext=dummyHeadnext;
ii. d u m m y H e a d → n e x t = n e w N o d e ; dummyHead \to next = newNode; dummyHeadnext=newNode;
iii. s i z e + + ; size++; size++;
请添加图片描述

    void addAtHead(int val) {
        Node* newNode = new Node(val);
        newNode -> next = dummyHead -> next;
        dummyHead -> next = newNode;
        size++;
    } 

(3) 尾插
因为要找的是最后一个结点,所以 c u r = d u m m y H e a d ; cur = dummyHead; cur=dummyHead;
找到最后一个结点后, c u r → n e x t = n e w n o d e ; cur \to next = newnode; curnext=newnode; s i z e + + ; size++; size++;

    void addAtTail(int val) {
        Node* newNode = new Node(val);
        Node* cur = dummyHead;
        while (cur -> next != NULL) {
            cur = cur -> next;
        }
        cur -> next = newNode;
        size++;
    }

(4) 普通插入
因为要找到第 i n d e x index index 个结点的前一个结点,所以 c u r = d u m m y H e a d ; cur = dummyHead; cur=dummyHead;
与头插类似:
i. n e w N o d e → n e x t = c u r → n e x t ; newNode \to next = cur \to next; newNodenext=curnext;
ii. c u r → n e x t = n e w N o d e ; cur \to next = newNode; curnext=newNode;
iii. s i z e + + size++ size++;
请添加图片描述

    void addAtIndex(int index, int val) {
        if (index > size || index < 0) {
            return ;
        }
        Node* newNode = new Node(val);
        Node* cur = dummyHead;
        while (index--) {
            cur = cur -> next;
        }
        newNode -> next = cur -> next;
        cur -> next = newNode;
        size++;
    }

(5) 删除
因为要找到第 i n d e x index index 个结点的前一个结点,所以 c u r = d u m m y H e a d ; cur = dummyHead; cur=dummyHead;
i. c u r → n e x t = c u r → n e x t → n e x t ; cur \to next = cur \to next \to next; curnext=curnextnext;
ii. s i z e ? ? ; size--; size??;
请添加图片描述

    void deleteAtIndex(int index) {
        if (index >= size || index < 0) {
            return;
        }
        Node* cur = dummyHead;
        while (index--) {
            cur = cur -> next;
        }
        Node* tmp = cur -> next;
        cur -> next = cur -> next -> next;
        delete tmp;
        size--;
    }

每次插入或删除操作都要记得更新 s i z e size size !
总代码:

class MyLinkedList {
public:
    struct Node {
        int val;
        Node* next;
        Node(int val): val(val), next(NULL) {}
    };
    MyLinkedList() {
        dummyNode = new Node(0);
        size = 0;
    }
    
    int get(int index) {
        if (index < 0 || index >= size) {
            return -1;
        }
        Node* cur = dummyNode -> next;
        while (index--) {
            cur = cur -> next;
        }
        return cur -> val;
    }
    
    void addAtHead(int val) {
        Node* newNode = new Node(val);
        newNode -> next = dummyNode -> next;
        dummyNode -> next = newNode;
        size++;
    }
    
    void addAtTail(int val) {
        Node* newNode = new Node(val);
        Node* cur = dummyNode;
        while (cur -> next != NULL) {
            cur = cur -> next;
        }
        cur -> next = newNode;
        size++;
    }
    
    void addAtIndex(int index, int val) {
        if (index < 0 || index > size) {
            return;
        }
        Node* newNode = new Node(val);
        Node *cur = dummyNode;
        while (index--) {
            cur = cur -> next;
        }
        newNode -> next = cur -> next;
        cur -> next = newNode;
        size++;
    }
    
    void deleteAtIndex(int index) {
        if (index < 0 || index >= size) {
            return;
        }
        Node *cur = dummyNode;
        while (index--) {
            cur = cur -> next;
        }
        Node *tmp = cur -> next;
        cur -> next = cur -> next -> next;
        delete tmp;
        size--;
    }
private:
    Node* dummyNode;
    int size;
};

/**
 * 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);
 */

学习时长: 1.5 hours

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 12:25:10  更:2022-10-31 12:27:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 19:46:54-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码