[C/C++] -- 链表

news2025/1/21 4:59:43

C/C++ 中链表是一种常见的数据结构,用于存储和组织数据。链表由节点(Node)组成,每个节点包含数据和指向下一个节点的指针。链表相对于数组的优势在于可以动态地分配内存,插入和删除操作效率高,但访问元素的随机性能较差。

1.简介

  • 链表节点结构定义

在 C/C++ 中定义链表节点的结构通常包含两部分:数据区域和指向下一个节点的指针

struct Node {
    int data;
    Node* next;
};
  • 创建链表

链表可以通过动态内存分配来创建。通过 new(C++)或 malloc(C)函数为每个节点分配内存,并通过指针串联节点形成链表。

Node* newNode(int data) {
    Node* node = new Node;
    node->data = data;
    node->next = nullptr;
    return node;
}

// 创建链表头节点
Node* head = newNode(1);
head->next = newNode(2);
head->next->next = newNode(3);
  • 插入节点

链表可以通过动态内存分配来创建。通过 new(C++)或 malloc(C)函数为每个节点分配内存,并通过指针串联节点形成链表。

Node* newNode = newNode(0);
newNode->next = head;
head = newNode;
  • 删除节点

删除节点时,需要调整前一个节点的指针,使其跳过当前节点,指向当前节点的下一个节点,并释放当前节点的内存。

// 删除头节点
Node* temp = head;
head = head->next;
delete temp;

// 删除中间或尾部节点
Node* prev = nullptr;
Node* curr = head;
while (curr != nullptr && curr->data != target) {
    prev = curr;
    curr = curr->next;
}
if (curr != nullptr) {
    prev->next = curr->next;
    delete curr;
}
  • 遍历链表

使用循环结构遍历链表中的所有节点,并访问节点的数据。

Node* temp = head;
while (temp != nullptr) {
    cout << temp->data << " ";
    temp = temp->next;
}
  • 查找节点

遍历链表查找特定值或条件的节点,可以实现搜索功能。

int target = 3;
Node* temp = head;
while (temp != nullptr && temp->data != target) {
    temp = temp->next;
}
if (temp != nullptr) {
    cout << "Node found with value " << target << endl;
} else {
    cout << "Node not found" << endl;
}
  • 双向链表

双向链表除了有指向下一个节点的指针外,还有指向前一个节点的指针,可以实现在链表两个方向上的遍历。

  • 循环链表

循环链表的最后一个节点指向头节点,形成一个闭环。可以实现循环遍历。

  • 内存管理

在使用链表时,需要注意内存管理,确保在删除节点时释放相应的内存,避免内存泄漏。

#include <iostream>
#include <cstdlib>

int main() {
    // 分配内存
    int *ptr = (int*)malloc(sizeof(int));
    
    if (ptr == nullptr) {
        std::cout << "内存分配失败!" << std::endl;
        return 1;
    }
    
    *ptr = 42;
    std::cout << "指针中的值为: " << *ptr << std::endl;
    
    // 释放内存
    free(ptr);
    
    return 0;
}

2.示例

输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
  • 递归法
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        if(!head||!head->next){
            /*
                直到当前节点的下一个节点为空时返回当前节点
                由于5没有下一个节点了,所以此处返回节点5
             */
            return head;
        }
        ListNode* newHead = reverseList(head->next);
        /*
           
            第一轮出栈,head为5,head.next为空,返回5
            第二轮出栈,head为4,head.next为5,执行head.next.next=head也就是5.next=4,
                      把当前节点的子节点的子节点指向当前节点
                      此时链表为1->2->3->4<->5,由于4与5互相指向,所以此处要断开4.next=null
                      此时链表为1->2->3->4<-5
                      返回节点5
            第三轮出栈,head为3,head.next为4,执行head.next.next=head也就是4.next=3,
                      此时链表为1->2->3<->4<-5,由于3与4互相指向,所以此处要断开3.next=null
                      此时链表为1->2->3<-4<-5
                      返回节点5
            第四轮出栈,head为2,head.next为3,执行head.next.next=head也就是3.next=2,
                      此时链表为1->2<->3<-4<-5,由于2与3互相指向,所以此处要断开2.next=null
                      此时链表为1->2<-3<-4<-5
                      返回节点5
            第五轮出栈,head为1,head.next为2,执行head.next.next=head也就是2.next=1,
                      此时链表为1<->2<-3<-4<-5,由于1与2互相指向,所以此处要断开1.next=null
                      此时链表为1<-2<-3<-4<-5
                      返回节点5
            出栈完成,最终头节点5->4->3->2->1
         */
        head->next->next = head;
        head->next = nullptr;
        return newHead;
    }
};

时间复杂度:O(n),其中 n 是链表的长度。需要对链表的每个节点进行反转操作。

空间复杂度:O(n),其中 n是链表的长度。空间复杂度主要取决于递归调用的栈空间,最多为 n 层。

  • 迭代

class Solution {
public:
        /*
            3个指针,prev,curr,next,它们组成一个前中后关系,从链表的一头移向另一头,起始时 prev 为空,结束时 next 为空
        */
    ListNode* reverseList(ListNode* head) {
        //过去为空,现在从头,未来不存
        ListNode* pre = nullptr;
        ListNode* cur = head;
        while(cur){
            ListNode* next = cur->next;//未来出于现在
            cur->next = pre;//现在指向过去
            pre = cur;//过去成为现在
            cur = next;//现在成为未来
        }
        return pre;
    }
};

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

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

相关文章

Word 操作

个性化设置 打开Microsoft Office后&#xff0c;可以在账户中设置Office的主题和背景。 如图所示&#xff0c;即可完成。 导航 如图所示&#xff0c;在Microsoft Office打开的docx文档中&#xff0c;鼠标点击左下角红框所示的地方&#xff0c;就会出现导航栏目。 护眼颜色 …

中央空调的计费方式

中央空调如何计费 电费计量型中央空调计费方法 计费原理:电费计量型就是通过计量空调末端的用电量&#xff0c;再根据用电量换算为冷量&#xff0c;统计中央空调系统中各用户的总冷量&#xff0c;再根据各用户的冷量比例来分摊费用。 优点: 电量参数容易计量&#xff0c;管理…

蓝桥杯-数的潜能-求快速幂

题目 思路 --将数字拆分成加和的形式&#xff0c;并且相乘。数据范围到10的18次方&#xff0c;暴力肯定不行&#xff0c;要找规律。拆分成1肯定不行&#xff0c;对乘法没有贡献&#xff0c;2可以&#xff0c;3也可以&#xff0c;4、5、6等大于3的数字都可以用2和3来表示。所以…

【博士每天一篇文献-综述】Brain network communication_ concepts, models and applications

阅读时间&#xff1a;2023-12-1 1 介绍 年份&#xff1a;2023 作者&#xff1a;Caio Seguin&#xff0c;Olaf Sporns印第安纳大学心理与脑科学系 期刊&#xff1a; nature reviews neuroscience 引用量&#xff1a;33 中文翻译参考&#xff1a;https://swarma.org/?p44524 …

【算法】差分算法(空调)

可用于求一个数组要变为另一个数组最少要改变多少次的次数 Farmer John 的 N 头奶牛对他们牛棚的室温非常挑剔。 有些奶牛喜欢温度低一些&#xff0c;而有些奶牛则喜欢温度高一些。 Farmer John 的牛棚包含一排 N 个牛栏&#xff0c;编号为 1…N&#xff0c;每个牛栏里有一头…

Emacs之极速复制文件名、绝对路径等快捷键(一百三十三)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

使用appuploder流程

使用appuploder流程笔记 1.如何没有账号去apple官网注册一个&#xff0c;地址&#xff1a;https://developer.apple.com/account 2.下载解压appuploder&#xff0c;双击打开&#xff0c;用刚刚注册的账号登录&#xff0c;下载地址&#xff1a;http://www.applicationloader.n…

鸿蒙Harmony应用开发—ArkTS-显式动画

提供全局animateTo显式动画接口来指定由于闭包代码导致的状态变化插入过渡动效。同属性动画&#xff0c;布局类改变宽高的动画&#xff0c;内容都是直接到终点状态&#xff0c;例如文字、canvas的内容、linearGradient等&#xff0c;如果要内容跟随宽高变化&#xff0c;可以使用…

数据库运行状况和性能监控工具

数据库监控是跟踪组织中数据库的可用性、安全性和性能的过程&#xff0c;它涉及通过跟踪各种关键指标来分析数据库的性能&#xff0c;确保数据库的正常运行并具有深入的可见性&#xff0c;并在出现潜在问题时触发即时警报&#xff0c;以采取主动措施来确保数据库的高可用性。 …

雀巢中国劳动力生态系统上线仪式圆满落幕

3月19日&#xff0c;雀巢中国劳动力生态系统上线仪式在雀巢北京总部举办。双方代表对项目进行了回顾&#xff0c;并就2024年的重点任务展开了深入讨论&#xff0c;共同探讨未来合作的方向和策略。 当天下午&#xff0c;劳动力效能典范游学之走进雀巢活动圆满落幕。活动展示了雀…

PFA过滤柱串联反应柱各种尺寸均可加工

PFA过滤柱层析柱定制串联反应柱&#xff0c;耐酸碱耐腐蚀和各种有机溶剂。

如何让intellij idea支持一个目录多个springtboot或maven项目

一、背景 有的时候&#xff0c;我们希望intellij idea 能像 eclipse 一样有workspace的概念&#xff0c;能在一个workspace目录里面引入多个项目&#xff0c;如&#xff1a; 我们有项目a、项目b&#xff0c;现在的项目几乎都是springboot项目&#xff08;即maven项目&#xf…

C#,图论与图算法,有向图(Directed Graph)的环(Cycle)的普通判断算法与源代码

1 检查该图是否包含循环 给定一个有向图,检查该图是否包含循环。如果给定的图形至少包含一个循环,则函数应返回true,否则返回false。 方法:深度优先遍历可用于检测图中的循环。连接图的DFS生成树。只有当图中存在后缘时,图中才存在循环。后边是从节点到自身(自循环)或…

#鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行

3 月 19 日&#xff0c;#鸿蒙生态创新中心#揭幕仪式在深圳湾科技生态园举行。 现场&#xff0c;深圳市南山区人民政府副区长李志娜发布《2024 年南山区支持鸿蒙原生应用发展首批政策措施清单》&#xff0c;从加强鸿蒙原生应用供给能力、推动鸿蒙原生应用产业集聚、完善鸿蒙原生…

Linux集群

前言&#xff1a; 环境准备&#xff1a;虚拟机&#xff0c;xshell&#xff0c;mysql&#xff0c;tomcat&#xff0c;jdk&#xff0c;centos 虚拟机安装centos可以参考博客&#xff1a;虚拟机安装centos 一&#xff0c;安装jdk 打开xshell 点击cftp&#xff0c;如果没有安装…

通过nginx+xray服务搭建及本地配置

一、xray服务配置 下载&#xff1a;https://github.com/XTLS/Xray-core 进入下载界面 这里我选择的是Xray-linux-64.zip 将文件解压到 /usr/local/xray 编辑配置文件/usr/local/xray/config.json uuid可以在v2ray客服端自动生成&#xff0c;也可以在UUID v4 生成器 - KKT…

Oracle数据库冷备份(实例)

冷备份 1、 select file#,name,bytes/1024/1024 mb from v$datafile; 2 、缩减 便于copy alter database datafile 2 resize 100m;show parameter spfilecreate undo tablespace u2 datafile /u01oracle/oradata/qq/u2.dbf size 2m autoextend on; //建新的 alter system…

《2023 IT行业项目管理调查报告》新鲜出炉!助力IT行业持续稳步发展

又一年&#xff01;2024年1月&#xff0c;禅道联合多方合作伙伴&#xff0c;发起了2023年IT行业项目管理调查问卷。经过2个多月的问卷收集与报告分析&#xff0c;《2023 IT行业项目管理调查报告》发布啦&#xff01; 我们希望通过这次调查&#xff0c;深入了解不同公司和个人在…

你知道什么是工业物联网吗?——青创智通

工业物联网解决方案-工业IOT-青创智通 工业物联网&#xff0c;简称IIoT&#xff08;Industrial Internet of Things&#xff09;&#xff0c;是指将物联网技术应用于工业领域&#xff0c;实现工业设备、系统和人之间的互联互通&#xff0c;以提高工业生产效率、降低运营成本并…

Vue.js+SpringBoot开发智能教学资源库系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 课程档案模块2.3 课程资源模块2.4 课程作业模块2.5 课程评价模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 课程档案表3.2.2 课程资源表3.2.3 课程作业表3.2.4 课程评价表 四、系统展示五、核心代…