算法复习:链表

news2024/11/29 2:58:44

链表定义

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

链表的遍历ListNode p=head; while(p!=null) p=p.next; 

找到链表的尾结点p=head; while(p.next!=null)p=p.next;

链表节点的个数

          p=head; cnt=0; //cnt与p不同步对应

          while(p!=null):cnt++; p=p.next

          cnt与p不同步对应的原因:

          while停止后,p为null,cnt为对应到最后一个节点上面

         规律:开始的时候同步和结束时候的同步规律是一致的。

链表删除

 注意:1.删除节点需要dummyNode  2.最后返回的是dummyNode.next而不是head.

       因为head可能被删掉

 ListNode dummyNode=new ListNode();

   dummyNode.next=head;

   (p.next为待删除节点)

    p.next=p.next.next;

   return dummyNode.next;

ListNode* deleteNode(ListNode* head, ListNode* p) {
        // 创建一个虚拟头节点,便于处理链表头部的删除操作
        ListNode dummyNode(0);
        dummyNode.next = head;
        // 将虚拟头节点的下一个节点指向原链表头节点
        ListNode* prev = &dummyNode;
        // 遍历链表,找到待删除节点的前驱节点
        while (prev->next&& prev->next != p) {
            prev = prev->next;
        }
        // 如果待删除节点存在,则进行删除操作
        if (prev->next) {
            prev->next = prev->next->next;
        } 
        else {
            std::cout << "Target node not found in the list." << std::endl;
        }
        // 返回处理后的新链表头节点(即原链表头节点)
        return dummyNode.next;
}

链表插入

  (1)头插法: dummyNode,p:

p.next=dummyNode.next;
dummyNode.next=p;

  (2)尾插法

tail,p:
   tail.next=p; tail=p;

   在尾插法的过程中,tail.next不需要清空:

   每次插入时tail.next都会重定向到待插入的节点

   最后tail.next=null

找到链表的第index个节点

int i=1;
p=head;
//计数变量和p索引始终同步对应:while停止后,i对应p.
while(i<index&&p!=null)
     p=p.next;
     i++;

链表翻转 dummyNode + 头插法

   ListNode dummyNode=new ListNode();
   dummyNode.next=null;
   ListNode p=head;
   if(head==null)return null;
   ListNode q=p.next;
   while(p!=null)
       q=p.next;
       p.next=dummyNode.next;
       dummyNode.next=p;
       p=q;
   return dummyNode.next;
两个链表第一个公共的节点

 (1)求两个链表长度n1,n2  

 (2)长的链表走|n1-n2|步,使两个链表长度相同

 (3)两个链表一起走,相等返回,走到头返回null

倒数第k个节点

(1) 求节点个数n

(2)求第n-k+1个节点

删除重复节点

 (1)增加虚拟头结点

   (2)链表节点的删除

     p.next=p.next.next

删除链表倒数第n个节点

   (1)添加虚拟头结点

   (2)求链表长度l

   (3)找第l-n的节点并删除

判断环

         如果有环:slow和fast走一定会相遇

         如果没有环:在有限次遍历链表后,一定为空

if head==null:return false//特判
slow=head;
fast=head.next;   
while(slow!=fast&&slow!=null&&slow.next!=null&&fast!=null&&fast.next!=null)
       slow=slow.next;
       fast=fast.next.next;
       if(slow==fast)return true;
       return false 
判断环的入口

(1)fast和slow置头结点,速度为2,1

(2)相遇后fast置头结点,速度为1

(3)fast和slow相遇的节点是入口

fast=pHead;
slow=pHead;
while(fast!=null&&fast.next!=null){
     fast=fast.next.next;slow=slow.next;
     if(fast==slow){
          fast=pHead;
          while(fast!=slow){
              fast=fast.next;
              slow=slow.next;}
          return fast;
return nullptr//如果遍历到空节点,说明没有环,返回null
合并两个排序的链表
p=head1,q=head2;
tail = dummyNode;
while(p!=null&&q!=null){
     if(p.val<q.val)tail.next=p;tail=p;p=p.next;
     else  tail.next=q;tail=q;q=q.next;
}

tail直接指向非空的一个链表,如果两个链表都是空,那么就指向空
tail.next=(p==null)?q:p;
return dummyNode.next;
回文链表

存储链表的值

指定区间反转链表

思路:切断后反转局部链表后重接回去。node1,node2,..,p,start,...end,q...noden

需要找到p,q,start,end

 (1)把区间的链表单独拎出来:

 p.next=null; end.next=null;

 (2)反转区间reverse

 (3)重写接回去

  reverse(start);

增加虚拟头结点:

  如果说从第一个开始就翻转,那么就得分情况讨论,所以要添加一个虚拟头结点。

奇偶链表

给定单链表的头节点 head ,将所有索引为奇数的节点和索引为偶数的节点分别组合在一起,然后返回重新排序的列表。 O(1) 的额外空间复杂度和 O(n) 的时间复杂度

两个虚拟头结点,使用尾插法,然后合并到一起。

ListNode *odd = new ListNode(0);
ListNode *even = new ListNode(0);

 ListNode *tail1=odd;
 ListNode *tail2=even;
 ListNode *p = head;
 int idx=1;
  while(p!=nullptr){
       if(idx%2!=0){
                tail1->next=p;
                tail1=p;
                p=p->next;
                idx++;
        }else{
                tail2->next=p;
                tail2=p;
                p=p->next;
                idx++;
            }
        }
//最后需要把tail2->next置空
        tail2->next=nullptr;
        tail1->next=even->next;
        return odd->next;
 }

尾插法最后置空,否则会出现野指针错误。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1560113.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

windows上配置Redis主从加哨兵模式实现缓存高可用

一、哨兵模式 哨兵&#xff08;sentinel&#xff09;是Redis的高可用性(High Availability)的解决方案&#xff1a;由一个或多个sentinel实例组成sentinel集群可以监视一个或多个主服务器和多个从服务器。当主服务器进入下线状态时&#xff0c;sentinel可以将该主服务器下的某…

基于PHP的新闻管理系统(用户发布版)

有需要请加文章底部Q哦 可远程调试 基于PHP的新闻管理系统(用户发布版) 一 介绍 此新闻管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。本新闻管理系统采用用户发布新闻&#xff0c;管理员审核后展示模式。 技术栈&am…

编曲知识15:重复段落编写 尾奏编写 家庭工作室搭建 硬件设备使用常识

15 重复段落编写 尾奏编写 家庭工作室搭建 硬件设备使用常识小鹅通-专注内容付费的技术服务商https://app8epdhy0u9502.pc.xiaoe-tech.com/live_pc/l_6602a586e4b0694cc051476b?course_id=course_2XLKtQnQx9GrQHac7OPmHD9tqbv 重复段落设计 第二段落指代间奏过后的段落 第二…

docker环境中宿主机防火墙添加ssh无法生效的问题分析

背景 在部署了docker容器的环境中&#xff0c;要在防火墙开通22端口&#xff0c;即ssh服务&#xff0c;以便在终端可以正常登陆。使用firewall-cmd在docker区域添加了22端口&#xff0c;但是没有起作用。后再public区域添加22端口才起作用。为什么docker区域不起作用&#xff…

数据结构与算法 顺序栈的基本运算

一、实验内容 编写一个程序sqstack.cpp&#xff0c;实现顺序栈的各种基本运算&#xff0c;并在此基础上写一个程序exp6.cpp,实现以下功能 初始化栈s判断栈是否为空依次进栈元素a,b,c,d,e判断栈是否为空输出出栈序列判断栈是否为空释放栈 二、实验步骤 1、sqstack.cpp 2、ex…

windows-MySQL5.7安装

1.安装包下载 https://downloads.mysql.com/archives/community/&#xff08;社区版下载链接&#xff09; 选择Archives可以下载历史包&#xff0c;此处使用5.7.43 2.解压文件 解压文件到你指定安装的目录&#xff1a;解压完成后在mysql-5.7.43-winx64下新建文件my.ini和d…

python中的deque详解

文章目录 摘要示例1:基本使用示例2:使用maxlen限制队列长度示例3:使用deque实现滑动窗口算法示例 4: 使用 deque 实现旋转数组示例 5: 使用 deque 实现最大/最小栈示例 6: 使用 deque 实现广度优先搜索(BFS)摘要 deque(双端队列)是Python标准库collections模块中的一个…

从0配置React

在本地安装和配置React项目&#xff0c;您可以使用create-react-app这个官方推荐的脚手架工具。以下是安装React的步骤&#xff0c;包括安装Node.js、使用create-react-app创建React应用&#xff0c;以及启动开发服务器。 下载安装node.js运行以下命令&#xff0c;验证Node.js…

《操作系统导论》第16章读书笔记:分段

《操作系统导论》第16章读书笔记&#xff1a;分段 —— 杭州 2024-03-31 夜 文章目录 《操作系统导论》第16章读书笔记&#xff1a;分段0.前言1.分段&#xff1a;泛化的基址/界限2.我们引用哪个段&#xff1f;3.栈怎么办4.支持共享5.细粒度与粗粒度的分段、操作系统支持6.小结7…

从vrrp、bfd、keepalived到openflow多控制器--理论篇

vrrp 在一个网络中&#xff0c;通常会使用vrrp技术来实现网关的高可用。 vrrp&#xff0c;即Virtual Router Redundancy Protocol&#xff0c;虚拟路由冗余协议。 应用场景 典型的如下面这个例子&#xff1a; 当Router故障后&#xff0c;将会导致HostA-C都无法连接外部的I…

嵌入式linux学习之opencv交叉编译

1.下载opencv源码 OpenCV官方源码下载链接为https://opencv.org/releases/&#xff0c;选择3.4.16版本下载。放在ubuntu系统~/opencv文件夹中&#xff0c;解压缩&#xff0c;opencv文件夹中新建build和install文件夹用于存放编译文件和安装文件&#xff1a; 2. 安装编译工具…

springboot配置文件application.properties,application.yml/application.yaml

application.properties Springboot提供的一种属性配置方式&#xff1a;application.properties 初始时配置文件中只有一行语句。 启动时&#xff0c;比如tomcat的端口号默认8080&#xff0c;路径默认。如果我们要改变端口号及路径之类的可以在application.properties中配置。…

【C语言环境】Sublime中运行C语言时MinGW环境的安装

要知道&#xff0c;GCC 官网提供的 GCC 编译器是无法直接安装到 Windows 平台上的&#xff0c;如果我们想在 Windows 平台使用 GCC 编译器&#xff0c;可以安装 GCC 的移植版本。 目前适用于 Windows 平台、受欢迎的 GCC 移植版主要有 2 种&#xff0c;分别为 MinGW 和 Cygwin…

【算法竞赛进阶指南】0x11 栈

0x11 栈 基础应用 两个栈维护前面区间的最小元素 41. 包含min函数的栈 - AcWing题库 可以开个小根堆维护最小值&#xff0c;但是这样时间是logN的。如果只用一个变量来存&#xff0c;一旦出现了出栈操作就无从下手了。因此用一个线性结构来保存每个历史时刻的最小值。 开两个…

vue3封装Element分页

配置当前页 配置每页条数 页面改变、每页条数改变都触发回调 封装分页 Pagination.vue <template><el-paginationbackgroundv-bind"$attrs":page-sizes"pageSizes"v-model:current-page"page"v-model:page-size"pageSize":t…

常用字符串函数及模拟实现

1.strlen() 用法:求字符串长度 size_t strlen(const char *Str) 参数:字符串的起始地址,可以传地址也可以直接传一个字符串 返回值:字符串长度 模拟实现: 自己实现求字符串长度的函数(三种方法)-CSDN博客 2.strcpy() 用法:拷贝字符串 char* strcpy(char*_Destination,co…

【PduR路由】IPduM模块详细介绍

目录 1.IpduM功能简介 2.IpduM模块依赖的其他模块 2.1RTE (BSW Scheduler) 2.2PDU Router 2.3COM 3.IpduM功能详解 3.1 功能概述 3.2 I-PDU多路复用I-PDU Multiplexing 3.2.1 Definitions and Layout 3.2.2通用功能描述 General 3.2.3模块初始化 Initialization 3.…

fpga_awb

色温: sesor原始图像中的白色如果不经AWB处理&#xff0c;在高色温(如阴天)下偏蓝&#xff0c;在低色温下偏黄。 引入白平衡算法 而AWB的核心就是调整图像色温&#xff0c;使得摄像头采集的图像更加真实&#xff0c;达到人眼观察的效果。 白平衡一般通过调节传感器输出图像RGB…

CCF-CSP19<2020-06>-第1/2题

202006-1 线性分类器 题目&#xff1a;202006-1 题目分析&#xff1a; 给定n个点&#xff0c;并标记为AB两类&#xff0c;问给定直线是否能将其分为两个点集。 简单数学知识&#xff0c;点在直线上满足axbyc0&#xff0c;点在直线割平面所得的上下其值会正负相反。 AC代码…

信息安全技术基础知识总结

一、信息安全基础知识 信息安全基本要素&#xff1a; 1. 机密性&#xff08;C&#xff09;&#xff1a;确保信息不暴露给未授权的实体或进程 2. 完整性&#xff08;I&#xff09;&#xff1a;只有得到允许的人才能修改数据&#xff0c;并且能够判别出数据是否已被篡改 3. 可用性…