【数据结构与算法篇】单链表及相关OJ算法题

【数据结构与算法篇】单链表及相关OJ算法题

🥕个人主页:开敲🍉

🔥所属专栏:数据结构与算法🍅

🌼文章目录🌼

1. 单链表的实现(近300行实现代码)

1.1 SList.h 头文件的声明

1.2 SList.c 源文件的定义

1.3 Test.c 源文件的测试

2.  OJ算法题

  2.1 206. 反转链表 - 力扣(LeetCode)

  2.2 203. 移除链表元素 - 力扣(LeetCode)

  2.3 876. 链表的中间结点 - 力扣(LeetCode)

1. 单链表的实现(近300行实现代码)

1.1 SList.h 头文件的声明

#pragma once


#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef int SLDataType;

typedef struct SListNode SL;

struct SListNode
{
    SLDataType value;
    SL* next;
};


//打印
void SLPrint(SL* phead);x


//申请空间
SL* SLBuyNode(SLDataType x);


//尾插
void SLPushBack(SL** pphead, SLDataType x);


//头插
void SLPushHead(SL** pphead, SLDataType x);

//指定插入
void SLPushDesi(SL** pphead,int y,SLDataType x);


//尾删
void SLPopBack(SL** pphead);


//头删
void SLPopHead(SL** pphead);

//指定删除
void SLPopDesi(SL** pphead, int y);


//查找
void SLFind(SL* pphead, int y);

//更改
void SLChange(SL** pphead, int y, SLDataType x);

1.2 SList.c 源文件的定义

#define _CRT_SECURE_NO_WARNINGS 1


#include "SList.h"

//打印
void SLPrint(SL* phead)
{
    SL* pcur = phead;
    while(pcur)
    {
        printf("%d->", pcur->value);
        pcur = pcur->next;
    }
    printf("NULL\n");
}


//申请空间
SL* SLBuyNode(SLDataType x)
{
    SL* pcur = (SL*)malloc(sizeof(SL));
    if (pcur == NULL)
    {
        perror("maolloc");
        exit(-1);
    }
    pcur->value = x;
    pcur->next = NULL;
    return pcur;
}

//尾插
void SLPushBack(SL** pphead, SLDataType x)
{
    SL* find = SLBuyNode(x);
    SL* pcur = *pphead;
    if ((*pphead) == NULL)
    {
        *pphead = find;
    }
    else
    {
        while (pcur->next)
        {
            pcur = pcur->next;
        }
        pcur->next = find;
    }
}

//头插
void SLPushHead(SL** pphead, SLDataType x)
{
    SL* find = SLBuyNode(x);
    if ((*pphead) == NULL)
    {
        *pphead = find;
    }
    else
    {
        find->next = *pphead;
        *pphead = find;
    }
}

//寻找
SL* FindSList(SL* pf, int y)
{
    SL* pcur = pf;
    while (y - 2)
    {
        if (pcur == NULL)
        {
            return NULL;
        }
        pcur = pcur->next;
        y--;
    }
    return pcur;
}


//指定插入
void SLPushDesi(SL** pphead, int y , SLDataType x)
{
    assert(*pphead&&pphead);
    SL* pcur = FindSList(*pphead, y);
    if (!pcur)
    {
        printf("插入越界,无法在此处插入数据!\n");
        exit(-1);
    }
    SL* ptmp = SLBuyNode(x);
    ptmp->next = pcur->next;
    pcur->next = ptmp;
}

//尾删
void SLPopBack(SL** pphead)
{
    assert(*pphead);
    if ((*pphead)->next == NULL)
    {
        free(*pphead);
        *pphead = NULL;
        return;
    }
    SL* pcur = *pphead;
    SL* ptmp = *pphead;
    while (pcur->next)
    {
        pcur = pcur->next;
        while (ptmp->next->next)
        {
            ptmp = ptmp->next;
        }
    }
    ptmp->next = NULL;
    free(pcur);
}


//头删
void SLPopHead(SL** pphead)
{
    assert(pphead&&*pphead);
    SL* pcur = *pphead;
    if ((*pphead)->next == NULL)
    {
        free(*pphead);
        *pphead = NULL;
        return;
    }
    (*pphead) = (*pphead)->next;
    free(pcur);
}

//指定删除

void SLPopDesi(SL** pphead, int y)
{
    assert(pphead&&*pphead);
    SL* pcur = FindSList(*pphead, y);
    SL* ptmp = pcur->next;
    if (!(pcur->next))
    {
        printf("删除越界,无法在此处删除数据!\n");
        return;
    }
    pcur->next = pcur->next->next;
    free(ptmp);
}


//查找
void SLFind(SL* pphead, int y)
{
    assert(pphead);
    SL* pcur = FindSList(pphead, y);
    if (!(pcur->next))
    {
        printf("查询失败!\n");
        return;
    }
    printf("查询成功!\n");
    printf("该位置数据为:%d\n", pcur->next->value);
    return;
}


//更改
void SLChange(SL** pphead, int y, SLDataType x)
{
    assert(*pphead);
    SL* pcur = FindSList(*pphead, y);
    if (!(pcur->next))
    {
        printf("更改失败,该位置无数据可更改!\n");
        return;
    }
    pcur->next->value = x;
}

1.3 Test.c 源文件的测试

#define _CRT_SECURE_NO_WARNINGS 1

#include "SList.h"


void TestSList()
{
    SL* plist = NULL;

//尾插
    SLPushBack(&plist, 1);
    SLPushBack(&plist, 2);
    SLPushBack(&plist, 3);
    SLPushBack(&plist, 4);
    SLPrint(plist);//打印

//头插

    SLPushHead(&plist, 0);
    SLPrint(plist);//打印

//指定插入

    SLPushDesi(&plist, 3, 5);
    SLPrint(plist);

//越界指定插入

    SLPushDesi(&plist, 7, 10);
    SLPrint(plist);

//尾删

    SLPopBack(&plist);
    SLPrint(plist);

//头删

    SLPopHead(&plist);
    SLPrint(plist);

//指定删除

    SLPopDesi(&plist, 3);
    SLPrint(plist);

//指定删除越界

    SLPopDesi(&plist, 5);


//查找

    SLFind(plist, 4);

//查找越界

    SLFind(plist, 5);

//更改

    SLChange(&plist, 3, 1);
    SLPrint(plist);

 

//更改越界

    SLChange(&plist, 5, 1);

}


int main()
{
    TestSList();
    return 0;
}

2.  OJ算法题

  2.1 206. 反转链表 - 力扣(LeetCode)

//思路:三指针解法。指针pf1开始指向NULL,指针pf2开始指向头节点,指针pf3指向pf2中的next节点,三个同时往后遍历,当pf2走到NULL时,pf1就是要返回的头节点

struct ListNode* reverseList(struct ListNode* head)

{

    struct ListNode* pf1 = NULL;

    struct ListNode* pf2 = head;

    while(pf2)

    {

        struct ListNode* pf3 = pf2->next;

        pf2->next = pf1;

        pf1 = pf2;

        pf2 = pf3;

    }

    return pf1;

}

  2.2 203. 移除链表元素 - 力扣(LeetCode)

//思路:遍历。使用指针pf1放头节点,遍历链表,如果pf1->->val等于题目所给val,则直接将当前next指向next->next,跳过val所在节点

//需要注意的是,需要考虑链表中的val都是题目所给val已经空链表的情况

struct ListNode* removeElements(struct ListNode* head, int val)

{

    while(head!=NULL&&(head->val)==val)

    {

        head = head->next;

    }

    if(!head)

    {

        return head;

    }

    struct ListNode* pf1 = head;

    while(pf1->next)

    {

        if((pf1->next->val)==val)

        {

            pf1->next = pf1->next->next;

        }

        else

        {

            pf1 = pf1->next;

        }

    }

    return head;

}

  2.3 876. 链表的中间结点 - 力扣(LeetCode)

//思路:快慢指针算法,这种寻找中间点的算法题使用快慢指针会非常便捷高效。主要思路就是指针pf1每次走一个节点,指针pf2每次走两个节点,当pf2走到末节点或走出链表时,pf1所指向的就是需要返回的中间节点。

struct ListNode* middleNode(struct ListNode* head)

{

    struct ListNode* pf1 = head;

    struct ListNode* pf2 = head;

    while(pf2&&pf2->next)

    {

        pf2 = pf2->next->next;

        pf1 = pf1->next;

    }

    return pf1;

}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

码蹄集部分题目(第五弹;OJ赛2024年第10期)

&#x1f40b;&#x1f40b;&#x1f40b;竹鼠通讯&#xff08;钻石&#xff1b;分治思想&#xff1b;模板题&#xff1a;就算几何平面点对问题&#xff09; 时间限制&#xff1a;3秒 占用内存&#xff1a;128M &#x1f41f;题目描述 在真空中&#xff0c;一块无限平坦光滑…

Java毕业设计 基于SpringBoot vue流浪动物救助网站

Java毕业设计 基于SpringBoot vue流浪动物救助网站 SpringBoot 流浪动物救助网站 功能介绍 首页 图片轮播 动物领养/捐赠 留言 论坛 发布帖子 公告信息 商品信息 添加购物车 立即购买 寻宠请求 购物车 注册登录 个人中心 余额充值 收货地址 动物收藏 动物领养审核 商品订单 …

最简洁的Docker环境配置

Docker环境配置 Docker 是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中&#xff0c;然后发布到任何流行的 Mac、Linux或Windows操作系统的机器上&#xff0c;也可以实现虚拟化。容器是完全使用沙箱机制&#xff0c;相互之间不…

基于Java+SpringBoot+Vue美容院业务管理系统(源码+文档+部署+讲解)

一.系统概述 悦己美容院后台管理系统的目的是让使用者可以更方便的将人、设备和场景更立体的连接在一起。能让用户以更科幻的方式使用产品&#xff0c;体验高科技时代带给人们的方便&#xff0c;同时也能让用户体会到与以往常规产品不同的体验风格。 与安卓&#xff0c;iOS相比…

100道面试必会算法-20-全排列

100道面试必会算法-20-全排列 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]示例 2&#…

Vue的模块化开发初探

文章目录 Vue的模块化开发初探一 概述二 步骤2.1 下载必须模块2.2 安装Live Server插件2.3 编写代码2.4 运行结果 三 总结四 参考资料 Vue的模块化开发初探 一 概述 Vue是一个渐进式JavaScript框架&#xff0c;可以按需引入部分功能&#xff0c;而不必全量引入整个框架。 二…

20240324-1-集成学习面试题EnsembleLearning

集成学习面试题 1. 什么是集成学习算法&#xff1f; 集成学习算法是一种优化手段或者策略&#xff0c;将多个较弱的模型集成模型组&#xff0c;一般的弱分类器可以是决策树&#xff0c;SVM&#xff0c;KNN等构成。其中的模型可以单独进行训练&#xff0c;并且它们的预测能以某…

python安装(window环境)

1.下载安装文件 首先推荐去官网下载最新版本&#xff0c;但是我这边官网打开很慢&#xff0c;而且下载的时候也很慢&#xff0c;翻墙也不行。所以我最终选择了非官方下载。 官网&#xff1a;Download Python | Python.org 中文官网&#xff1a;Python下载 | Python中文网 官…

牛客周赛39 --- G -- 小红不想做平衡树 -- 题解

小红不想做平衡树&#xff1a; 思路解析&#xff1a; 好数组的定义为 恰好翻转一个区间是得&#xff0c;这个区间变为升序的。 那么就有五种情况&#xff1a; 1.本身数组就升序的&#xff0c; 翻转一个长度为1的区间后&#xff0c;数组仍为升序 2.本身数组就降序的&#xf…

跨框架探索:React Redux 和 Vuex 对比分析快速掌握React Redux

React Redux 和 Vuex 都是前端状态管理库&#xff0c;分别用于 React 和 Vue.js 框架。 它们都提供了一套规范的状态管理机制&#xff0c;帮助开发者更好地组织和管理应用状态。下面是它们的一些异同点&#xff1a; 相同点&#xff1a; 中心化状态管理&#xff1a;两者都提…

环形链表 II - LeetCode 热题 26

大家好&#xff01;我是曾续缘&#x1f61b; 今天是《LeetCode 热题 100》系列 发车第 26 天 链表第 5 题 ❤️点赞 &#x1f44d; 收藏 ⭐再看&#xff0c;养成习惯 环形链表 II 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xf…

docker部署coredns服务器

创建文件夹 mkdir /coredns/config/添加一个CoreDNS配置文件 cat >/coredns/config/Corefile<<EOF.:53 {forward . 114.114.114.114:53log}EOF启动docker docker run -d --name coredns --restartalways \-v /coredns/config:/etc/coredns \-p 53:53/udp \regist…

HarmonyOS 开发-短视频切换实现案例

介绍 短视频切换在应用开发中是一种常见场景&#xff0c;上下滑动可以切换视频&#xff0c;十分方便。本模块基于Swiper组件和Video组件实现短视频切换功能。 效果图预览 使用说明 上下滑动可以切换视频。点击屏幕暂停视频&#xff0c;再次点击继续播放。 实现思路 使用Sw…

一文了解ERC404协议

一、ERC404基础讲解 1、什么是ERC404协议 ERC404协议是一种实验性的、混合的ERC20/ERC721实现的&#xff0c;具有原生流动性和碎片化的协议。即该协议可让NFT像代币一样进行拆分交易。是一个图币的互换协议。具有原生流动性和碎片化的协议。 这意味着通过 ERC404 协议&#xf…

混淆时,编译器优化导致通过反射赋值的类被清空问题

有几个反射赋值的类&#xff0c;之前一直是 keep 整个class的&#xff0c;现在要求对class的路径进行混淆。 当我启用混淆后&#xff0c;发现整个类的内容被清空了。 // 原始的类内容public class BaseLoadData {property("config_data1")public static String dat…

R语言数据可视化:ggplot2绘图系统

ggpolt2绘图系统被称为R语言中最高大上的绘图系统&#xff0c;使用ggplot2绘图系统绘图就像是在使用语法创造句子一样&#xff0c;把数据映射到几何客体的美学属性上。因此使用ggplot2绘图系统的核心函数ggplot来绘图必须具备三个条件&#xff0c;数据data&#xff0c;美学属性…

如何开始用 C++ 写一个光栅化渲染器?

光栅化渲染器是计算机图形学中最基础且广泛应用的一种渲染技术&#xff0c;它将三维模型转化为二维图像。下面我们将逐步介绍如何使用C语言从零开始构建一个简单的光栅化渲染器。 一、理解光栅化渲染原理 光栅化是一种将几何数据&#xff08;如点、线、三角形&#xff09;转换…

视频拍摄后如何用二维码分享?在线制作视频二维码的方法

现在很多人会将拍摄的视频内容用生成二维码的方式来分享给其他人&#xff0c;与以前使用微信、QQ、网盘等形式相比&#xff0c;二维码能够更加简单快捷的将视频传递给其他人查看&#xff0c;不需要下载缓存占用扫码者的内存&#xff0c;提供更好的用户体验效果。 视频转二维码…

大语言模型及提示工程在日志分析任务中的应用 | 顶会IWQoS23 ICPC24论文分享

本文是根据华为技术专家陶仕敏先生在2023 CCF国际AIOps挑战赛决赛暨“大模型时代的AIOps”研讨会闪电论文分享环节上的演讲整理成文。 BigLog&#xff1a;面向统一日志表示的无监督大规模预训练方法 BigLog: Unsupervised Large-scale Pre-training for a Unified Log Represen…

低代码平台适合谁用?业务岗能用它做什么?开发岗能用它做什么?一文讲清!

近期&#xff0c;低代码开发平台以其独特的魅力&#xff0c;迅速引发了大众的广泛关注。众多人士纷纷寻求了解各类低代码产品&#xff0c;以探究其功能与特点。 然而&#xff0c;有些人可能因一两款产品的体验不佳&#xff0c;便对整个低代码行业产生了偏见。但我要指出的是&am…