leetcode-代码随想录-链表-链表总结篇

理论基础

链表: 每个节点由两部分组成:数据域和指针域(存放指向下一个节点的指针);入口节点称为头节点;最后一个节点的指针域指向NULL(空指针)。

分类:

  • 单链表
  • 双链表:一个节点有两个指针域分别指向前一个节点及后一个节点。可以双向查询。
  • 循环链表:头尾相连。

存储方式: 分散存储在内存空间中;

定义:

c++ 复制代码
struct ListNode{
	int val;
	ListNode* next;
	ListNode(int x): val(x), next(nullptr){}
};
经典题目

虚拟头节点: ListNode* dummyhead = new ListNde(0);

链表头节点索引为 0;

无论是插入节点还是删除节点:cur指针必须指向被操作节点的前一个节点;

移除链表元素
  1. 定义虚拟头节点 dummyhead = head
  2. 定义一个指针 cur = dummyhead
  3. cur->next != null的情况下,遍历链表;
  4. 判断 cur->next->val 是否等于 val
  5. 找到后,定义temp变量存储该节点,利用cur->next = cur->next->next实现移除操作;
  6. 释放被删除节点 temp的内存。
设计链表
  1. 链表节点的定义及其初始化:

    • 定义链表大小 _size = 0 ;
    • 定义虚拟头节点 dummyhead;
  2. 链表最后插入一个节点

    • 创建一个新节点 newNode;
    • cur = dummyhead;
    • 使cur移动到当前链表的最后一个节点:while(cur->next != NULL) cur = cur->next;
    • cur->next = newNode;
    • _size++;
  3. 获取链表中下标为 index 的节点的值

    • 若 index 不在范围内,返回 -1;
    • cur = dummyhead->next;
    • 使cur移动到index节点处:while(index--),cur = cur->next;
    • 循环结束,cur->val 即是 index节点的值;
  4. 在链表最前面插入一个节点

    • 创建一个新节点 newNode;
    • cur = dummyhead;
    • newNode->next = cur->next;
    • cur->next = newNode;
    • _size++;
  5. 在第index节点前插入一个新节点;

    • 若 index > _size,直接返回;若index < 0, index = 0;
    • 创建一个新节点 newNode;
    • cur = dummyhead;
    • 使cur移动到第index节点前的一个节点处:while(cur->next != NULL) cur = cur->next;
    • newNode->next = cur->next;
    • cur->next = newNode;
    • _size++;
反转链表


  1. 定义两个指针:pre = NULL; cur = head;
  2. 能实现反转的条件:cur != NULL
  3. 反转:
    • 先保存 cur->next(后续会改变其指向):temp = cur->next;
    • cur->next = pre;
  4. 移动:先移动pre = cur; 再移动cur = temp;
  5. 返回 pre;
两两交换链表中的节点



交换时,cur要指向交换的两个节点的前一个节点

  1. cur = dummyhead;
  2. 能实现交换的条件:cur->next != NULL && cur->next->next != NULL;
  3. 交换:
    • 先保存会被改变的节点:temp = cur->next; temp1 = cur->next->next->next;
    • cur->next = cur->next->next;
    • cur->next->next = temp;
    • temp->next = temp1;
  4. 移动:cur = cur->next->next;
删除链表中的倒数第index个节点
  1. 定义两个指针:fast 和 slow 都指向 dummyhead;
  2. fast先移动 index+1个节点;
  3. 当 fast != NULL 时,fast和 slow同时向后移动。
  4. 此时 slow 指向倒数第index个节点的前一个节点;利用 slow->next = slow->next->next删除节点;
链表相交
  1. 两个链表分别定义一个指针: curA = headA,curB = headB;
  2. 遍历两个链表分别求出其对应的长度:lenA 、lenB;
  3. 让curA和curB再次指向各自的头指针:curA = headA,curB = headB;
  4. 如果链表 A 的长度 大于 链表 B 的长度,对其长度和指针进行交换(swap函数),始终保持链表 A长度大于链表 B;
  5. 求出两者差值 gap,并将 curA向后移动 gap 个节点;
  6. 从 curA遍历两个链表,若 curA = curB,返回 curB(curA),(相交点),若没找到返回NULL。
判断是否成环
  1. 定义两个指针:fast = head,slow = head;
  2. 因为 fast每次走两个节点,slow每次走一个节点,因此循环判断条件是:fast != NULL && fast->next != NULL;
  3. 若 fast = slow,说明存在环
  4. 定义两个指针 index1 = head,index2 = slow;
  5. 当 index1 != index2时, index1 和index2 两个指针逐步向后移;
  6. 只要 index1 == index2 ,则 index1(index2)就是环的入口节点;若无环,返回NULL;
相关推荐
Dreams_l4 小时前
顺序表(Arraylist)和链表(Linkedlist)
数据结构·链表
月亮被咬碎成星星4 小时前
LeetCode[28]找出字符串中第一个匹配项的下标(KMP版本)
算法·leetcode
Dominic_Holmes5 小时前
代码随想录算法训练营Day30 | 01背包问题(卡码网46. 携带研究材料)、Leetcode416.分割等和子集
数据结构·python·算法·leetcode
大胆飞猪5 小时前
dfs二叉树中的深搜(回溯、剪枝)--力扣129、814、230、257
算法·leetcode·深度优先·dfs
一叶祇秋5 小时前
Leetcode - 双周赛135
算法·leetcode·职场和发展
小王努力学编程6 小时前
贪心算法学习C++
开发语言·c++·学习·算法·leetcode·贪心算法
tkevinjd8 小时前
并查集(力扣1971)
算法·leetcode·图论·并查集
星星火柴93611 小时前
数据结构:哈希表 | C++中的set与map
数据结构·c++·笔记·算法·链表·哈希算法·散列表
CppPlayer-程序员阿杜18 小时前
poll为什么使用poll_list链表结构而不是数组 - 深入内核源码分析
网络·c++·链表·list·poll
@hdd18 小时前
C++| 深入剖析std::list底层实现:链表结构与内存管理机制
c++·链表·list