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

2024-04-09 20:12

本文主要是介绍【数据结构与算法篇】单链表及相关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;

}

这篇关于【数据结构与算法篇】单链表及相关OJ算法题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/889102

相关文章

Redis的Zset类型及相关命令详细讲解

《Redis的Zset类型及相关命令详细讲解》:本文主要介绍Redis的Zset类型及相关命令的相关资料,有序集合Zset是一种Redis数据结构,它类似于集合Set,但每个元素都有一个关联的分数... 目录Zset简介ZADDZCARDZCOUNTZRANGEZREVRANGEZRANGEBYSCOREZ

Linux使用fdisk进行磁盘的相关操作

《Linux使用fdisk进行磁盘的相关操作》fdisk命令是Linux中用于管理磁盘分区的强大文本实用程序,这篇文章主要为大家详细介绍了如何使用fdisk进行磁盘的相关操作,需要的可以了解下... 目录简介基本语法示例用法列出所有分区查看指定磁盘的区分管理指定的磁盘进入交互式模式创建一个新的分区删除一个存

关于Maven生命周期相关命令演示

《关于Maven生命周期相关命令演示》Maven的生命周期分为Clean、Default和Site三个主要阶段,每个阶段包含多个关键步骤,如清理、编译、测试、打包等,通过执行相应的Maven命令,可以... 目录1. Maven 生命周期概述1.1 Clean Lifecycle1.2 Default Li

numpy求解线性代数相关问题

《numpy求解线性代数相关问题》本文主要介绍了numpy求解线性代数相关问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 在numpy中有numpy.array类型和numpy.mat类型,前者是数组类型,后者是矩阵类型。数组

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

Redis的Hash类型及相关命令小结

《Redis的Hash类型及相关命令小结》edisHash是一种数据结构,用于存储字段和值的映射关系,本文就来介绍一下Redis的Hash类型及相关命令小结,具有一定的参考价值,感兴趣的可以了解一下... 目录HSETHGETHEXISTSHDELHKEYSHVALSHGETALLHMGETHLENHSET

python中的与时间相关的模块应用场景分析

《python中的与时间相关的模块应用场景分析》本文介绍了Python中与时间相关的几个重要模块:`time`、`datetime`、`calendar`、`timeit`、`pytz`和`dateu... 目录1. time 模块2. datetime 模块3. calendar 模块4. timeit

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个