C/C++每日一练:查找链表的中间节点

链表(Linked List)

         链表是一种线性数据结构,由一系列节点(Node)通过指针链接在一起。与数组不同,链表中的元素在内存中不需要连续存储,每个节点包含两部分:

  • 数据部分:存储节点的值或数据。
  • 指针部分:存储指向下一个节点的地址(单链表)或上一个和下一个节点的地址(双向链表)。

         链表的类型主要有以下几种:

  • 单链表:每个节点只指向下一个节点。
  • 双向链表:每个节点既有指向下一个节点的指针,也有指向上一个节点的指针。
  • 循环链表:链表的最后一个节点指向链表的头节点,形成循环。

         链表的特点:

  • 动态大小:可以根据需要动态地增加或减少元素,无需预分配存储空间。
  • 插入/删除效率高:在链表的任意位置进行插入或删除操作只需修改指针,不涉及大量元素的移动,效率较高。
  • 随机访问效率低:由于链表不支持直接访问任意位置的元素,需要通过遍历来查找特定位置的节点。

         如下图所示:

题目要求

         给定一个单链表,编写一个算法来查找链表的中间节点。如果链表长度为奇数,则返回唯一的中间节点;如果为偶数,则返回两个中间节点中的第一个。

示例

假设链表为:1 -> 2 -> 3 -> 4 -> 5

  • 输出:节点 3

假设链表为:1 -> 2 -> 3 -> 4

  • 输出:节点 2

做题思路

         寻找链表的中间节点可以用快慢指针的方法。这种方法效率高且不需要额外的空间,适合单链表查找问题。

  1. 定义两个指针:slow 和 fast。
  2. slow 每次向前移动一步,fast 每次向前移动两步。
  3. 当 fast 指针遍历到达链表末尾时,slow 指针正好在链表的中间位置。
  4. 这种方法的时间复杂度为 O(n),空间复杂度为 O(1),是一种高效的解法。

过程解析

  1. 初始化两个指针 slow 和 fast,都指向链表的头节点。
  2. 通过循环控制 fast 每次移动两步,slow 每次移动一步。
  3. 当 fast 为 NULL 或 fast->next 为 NULL 时,结束循环,此时 slow 即为中间节点。

运用到的知识点

  • 链表的基本操作和定义
  • 指针的概念和指针操作
  • 快慢指针算法技巧
  • 时间和空间复杂度分析

示例代码

C 实现

#include <stdio.h>   // 包含标准输入输出库,用于输出打印函数
#include <stdlib.h>  // 包含标准库,用于内存分配// 定义链表节点结构体
struct Node {int data;            // 节点数据部分,存储整型数据struct Node* next;   // 指向下一个节点的指针
};// 创建新节点函数
struct Node* createNode(int data) {// 为新节点分配内存空间struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));// 初始化新节点的数据newNode->data = data;// 将新节点的指针设置为 NULL,表示链表的末尾newNode->next = NULL;return newNode;  // 返回创建好的新节点
}// 查找链表中间节点的函数
struct Node* findMiddle(struct Node* head) {struct Node *slow = head, *fast = head;  // 定义并初始化快慢指针,均指向链表头节点// 循环遍历链表,直到 fast 到达链表末尾while (fast != NULL && fast->next != NULL) {slow = slow->next;        // 慢指针每次向前移动一步fast = fast->next->next;  // 快指针每次向前移动两步}return slow;  // 当循环结束时,慢指针指向链表的中间节点
}// 打印链表的函数
void printList(struct Node* head) {struct Node* temp = head;  // 定义一个临时指针,用于遍历链表// 循环遍历链表,直到节点为空while (temp != NULL) {printf("%d -> ", temp->data);  // 打印当前节点的数据temp = temp->next;             // 移动到下一个节点}printf("NULL\n");  // 链表末尾指示为 NULL
}// 主函数
int main() 
{// 创建链表节点并连接,构造链表 1 -> 2 -> 3 -> 4 -> 5struct Node* head = createNode(1);head->next = createNode(2);head->next->next = createNode(3);head->next->next->next = createNode(4);head->next->next->next->next = createNode(5);printf("链表: ");printList(head);  // 调用函数打印链表// 查找链表的中间节点struct Node* middle = findMiddle(head);if (middle != NULL) {// 如果链表非空,打印中间节点的数据printf("The data of the middle node is: %d\n", middle->data);} else {// 如果链表为空,提示信息printf("the linked list is empty.\n");}return 0;  // 程序结束
}

C++ 实现

#include <iostream>   // 包含输入输出流库,用于控制台输出
using namespace std;  // 使用标准命名空间,避免每次使用 std:: 前缀// 定义链表节点类
class Node {
public:int data;      // 节点数据部分,存储整型数据Node* next;    // 指向下一个节点的指针// 构造函数,用于创建新节点并初始化数据Node(int data) {this->data = data;      // 初始化节点数据this->next = nullptr;   // 初始化指针为 nullptr 表示链表末尾}
};// 查找链表中间节点的函数
Node* findMiddle(Node* head) {Node *slow = head, *fast = head;  // 定义快慢指针,均初始化为链表头节点// 循环遍历链表,直到 fast 或 fast->next 到达链表末尾while (fast != nullptr && fast->next != nullptr) {slow = slow->next;        // 慢指针每次移动一步fast = fast->next->next;  // 快指针每次移动两步}return slow;  // 循环结束时,慢指针指向链表的中间节点
}// 打印链表的函数
void printList(Node* head) {Node* temp = head;  // 定义临时指针,用于遍历链表// 循环遍历链表,直到节点为空while (temp != nullptr) {cout << temp->data << " -> ";  // 打印当前节点的数据temp = temp->next;             // 移动到下一个节点}cout << "NULL" << endl;  // 链表末尾输出 NULL 表示链表终点
}int main() 
{// 创建链表节点并连接,构造链表 1 -> 2 -> 3 -> 4 -> 5Node* head = new Node(1);head->next = new Node(2);head->next->next = new Node(3);head->next->next->next = new Node(4);head->next->next->next->next = new Node(5);cout << "链表: ";printList(head);  // 打印链表// 查找链表的中间节点Node* middle = findMiddle(head);if (middle != nullptr) {// 如果链表非空,打印中间节点的数据cout << "The data of the intermediate node is: " << middle->data << endl;} else {// 如果链表为空,提示信息cout << "The linked list is empty" << endl;}return 0;  // 程序结束
}

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

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

相关文章

对称加密与非对称加密:密码学的基石及 RSA 算法详解

对称加密与非对称加密&#xff1a;密码学的基石及 RSA 算法详解 在当今数字化的时代&#xff0c;信息安全至关重要。对称加密和非对称加密作为密码学中的两种基本加密技术&#xff0c;为我们的数据安全提供了强大的保障。本文将深入探讨对称加密和非对称加密的特点、应用场景&…

PH47代码框架全局函数及功能类

PH47代码框架全局函数及功能类 概述 全局函数及功能类体系是PH47框架当中除了4个逻辑层之外最重要的组成部分之一&#xff0c;它们可以在 整个PH7 代码框架及用户代码中使用。常用全局函数及功能类为 PH7 代码框架提供了最常用和最基础的功能实现。 全局函数主要包含了对时间…

Spark 中的 RDD 分区的设定规则与高阶函数、Lambda 表达式详解

Spark 的介绍与搭建&#xff1a;从理论到实践_spark环境搭建-CSDN博客 Spark 的Standalone集群环境安装与测试-CSDN博客 PySpark 本地开发环境搭建与实践-CSDN博客 Spark 程序开发与提交&#xff1a;本地与集群模式全解析-CSDN博客 Spark on YARN&#xff1a;Spark集群模式…

Spring学习笔记_30——事务接口PlatformTransactionManager

PlatformTransactionManager是Spring框架中事务管理的核心接口&#xff0c;它负责管理事务的创建、提交和回滚等操作。 源码 /** Copyright 2002-2020 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* you m…

力扣 LeetCode 203. 移除链表元素(Day2:链表)

解题思路&#xff1a; 方法一&#xff1a;头节点和非头节点分开处理 方法二&#xff1a;定义一个dummy虚拟节点&#xff0c;后面的节点就可以采用相同的处理方式 注意&#xff1a; cur需要指向要删除的节点的上一个节点&#xff0c;因为要越过这一个被删除的节点 class Sol…

Python小游戏25——黄金矿工

首先&#xff0c;你需要安装Pygame库。 如果你还没有安装&#xff0c;可以使用以下命令进行安装&#xff1a; 【bash】 pip install pygame 【python】代码展示 import pygame import random # 初始化Pygame pygame.init() # 设置屏幕尺寸 screen_width 800 screen_height 60…

鸿蒙5.0版开发:订阅卡死事件(ArkTS)

在HarmonyOS 5.0中&#xff0c;开发者可以通过ArkTS订阅应用的卡死事件&#xff0c;以便在应用出现卡死时进行相应的处理。这不仅可以帮助开发者监控应用的稳定性&#xff0c;还可以在问题发生时快速定位问题原因。本文将详细介绍如何在ArkTS中订阅卡死事件&#xff0c;并提供示…

IEC60870-5-104 协议源码架构详细分析

IEC60870-5-104 协议源码架构 前言一、资源三、目录层级一二、目录层级二config/lib60870_config.hdependencies/READMEexamplesCMakeLists.txtcs101_master_balancedcs104_client_asyncmulti_client_servertls_clienttls_server说明 make这些文件的作用是否需要导入这些文件&a…

turbo c 2.0 画螺栓

代码; #include<graphics.h> void bolt(x0,y0,d,l) int x0,y0,d,l; {int x1,x2,x3,x4,x5,x6,x7,x8;int y1,y2,y3,y4,y5,r1,r2,b,c;if(l>2*d) b2*d;else b1;r11.5*d;r20.38*d;c0.1*d;x1x0-0.7*d;x2x0-0.61*d;x3x0-0.32*d;x4x00.8*d;x5x0l-b;x6x0l-c;x7x0l-0.05*d;x8x0…

网络服务综合项目-博客

一、运行环境&#xff1a; 主机主机名系统服务192.168.31.128Server-WebLinuxWeb192.168.31.129Server-NFS-DNSLinuxNFS 二、基础配置&#xff1a; 配置主机名开启防火墙并配置部分开启selinux并配置服务器之间使用ntp.aliyun.com进行时间同步服务器之间实现ssh免密登录 三…

衡石科技BI如何助力企业实现数字化转型

在当今数字化浪潮席卷全球的背景下&#xff0c;企业纷纷寻求通过数字化转型来降低成本、提升效率、优化决策&#xff0c;从而在激烈的市场竞争中脱颖而出。衡石科技&#xff0c;作为一家专注于商业智能&#xff08;BI&#xff09;与数据分析的创新型企业&#xff0c;通过其先进…

leetcode86:分隔链表

给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 示例 1&#xff1a; 输入&#xff1a;head [1,4,3,2,5,2], x 3 输出&am…

Android Mobile Network Settings | APN 菜单加载异常

问题 从log看是有创建APN对应的Controller&#xff08;功能逻辑是ok的&#xff09;&#xff0c;但是Mobile Network Settings无法显示&#xff08;UI异常&#xff09;。 日志分析 看似APN 菜单已经创建了&#xff0c;实际上并没有显示。 11-12 07:01:28.150 8773 8773 D Pr…

上海市计算机学会竞赛平台2020年4月月赛丙组永恒的生命游戏

题目背景 2020年4月11日&#xff0c;英国数学家 约翰霍顿康威&#xff08;John Horton Conway&#xff09;因为新型冠状病毒肺炎不幸逝世。他在群论、数论、代数、几何拓扑、理论物理、组合博弈论和几何等领域&#xff0c;都做出了重大贡献。他的离去是人类文明的损失。他最著…

php 之添加图片水印,根据比例计算水印的新尺寸

以下是 _imgWatermark 函数的中文注释和解析。该函数用于在图像上添加水印&#xff1a; function _imgWatermark($src_image, $water_image, $path_image , $position 10, $pct 30, $angle 15) {// 检查源图和水印图文件是否存在if (!is_file($src_image)) {$error 源图不…

表格理解专题(五)表头和数据项定义

在 Excel 中&#xff0c;表头和数据项的区分主要取决于数据的组织结构。简单来说&#xff0c;表头 是用来描述数据含义的标签&#xff0c;而 数据项 是表格中存储的实际值。下面我会列举不同情况下&#xff0c;什么是表头&#xff0c;什么是数据项。 1. 表头的定义 表头通常是…

Day09 C++ 存储类

2024.11.12 C 存储类 一、C 存储类 存储类定义 C 程序中变量/函数的范围&#xff08;可见性&#xff09;和生命周期。这些说明符放置在它们所修饰的类型之前。下面列出 C 程序中可用的存储类&#xff1a; auto&#xff1a;这是默认的存储类说明符&#xff0c;通常可以省略不…

FS8x 功能安全

fail-safe是电独立的和物理隔离的。fail-safe由自己的参考电压和电流提供,有自己的振荡器,有重复的模拟路径以最小化常见的故障,并有LBIST/ABIST来覆盖潜在故障。fail-safe根据设备部件号提供ASIL B或ASIL D遵从性。除非另有规定,fail-safe定时来自故障安全振荡器,其精度为…

项目模块十七:HttpServer模块

一、项目模块设计思路 目的&#xff1a;实现HTTP服务器搭建 思想&#xff1a;设计请求路由表&#xff0c;记录请求方法与对应业务的处理函数映射关系。用户实现请求方法和处理函数添加到路由表&#xff0c;服务器只接受请求并调用用户的处理函数即可。 处理流程&#xff1a; …

内网域环境、工作组、局域网等探针方案

1. 信息收集 1.1 网络收集 了解当前服务器的计算机基本信息&#xff0c;为后续判断服务器角色&#xff0c;网络环境做准备 systeminfo 详细信息 net start 启动服务 tasklist 进程列表 schtasks 计划任务&#xff08;受权限影响&#xff09; 了解当前服务器的网络接口信息…