数据结构-链表的基本操作

news2024/11/22 15:37:12

前言:

在dotcpp上碰到了一道题,链接放这了,这道题就是让你自己构建一遍链表的创建,插入节点,删除节点,获取节点,输出链表,题目给了几张代码图,不过不用管那些图,按自己的思路写一遍
也是这道题,让我第一次自己完整的去实现了一遍链表,通过题目来学,我一直都觉得效果是非常明显的
在学校老师教的数据结构,那本书是一本黄色外壳的书,不是说这书不好,书里代码采用的C和C++的混用,有的地方他用C实现,有地方他用C++实现,就感觉这对像我这种菜鸟很不友好,这让我自已写时,很容易出现错误,看半天看不出来

题目描述:

链表是数据结构中一种最基本的数据结构,它是用链式存储结构实现的线性表。它较顺序表而言在插入和删除时不必移动其后的元素。现在给你一些整数,然后会频繁地插入和删除其中的某些元素,会在其中某些时候让你查找某个元素或者输出当前链表中所有的元素。
下面给你基本的算法描述:
请添加图片描述
图1:链表类型的定义以及获得链表元素的算法描述
请添加图片描述
图2:链表的插入算法描述
请添加图片描述
图3:链表的删除算法描述
请添加图片描述
图4:链表的创建算法描述

输入格式:

输入数据只有一组,第一行有n+1个整数,第一个整数是这行余下的整数数目n,后面是n个整数。这一行整数是用来初始化列表的,并且输入的顺序与列表中的顺序相反,也就是说如果列表中是1、2、3那么输入的顺序是3、2、1。
第二行有一个整数m,代表下面还有m行。每行有一个字符串,字符串是“get”,“insert”,“delete”,“show”中的一种。如果是“get”或者“delete”,则其后跟着一个整数a,代表获得或者删除第a个元素;如果是“insert”,则其后跟着两个整数a和e,代表在第a个位置前面插入e;“show”之后没有整数。

输出格式

如果获取成功,则输出该元素;如果删除成功则输出“delete OK”;如果获取失败或者删除失败,则输出“get fail”以及“delete fail”。如果插入成功则输出“insert OK”,否则输出“insert fail”。如果是“show”则输出列表中的所有元素,如果列表是空的,则输出“Link list is empty”。注:所有的双引号均不输出。

样例输入:

3 3 2 1
21
show
delete 1
show
delete 2
show
delete 1
show
delete 2
insert 2 5
show
insert 1 5
show
insert 1 7
show
insert 2 5
show
insert 3 6
show
insert 1 8
show
get 2

样例输出:

1 2 3
delete OK
2 3
delete OK
2
delete OK
Link list is empty
delete fail
insert fail
Link list is empty
insert OK
5
insert OK
7 5
insert OK
7 5 5
insert OK
7 5 6 5
insert OK
8 7 5 6 5
7

解题思路:
不必去看那几张图,就依自己的思路写,链表就是结构体变量连起来,也就是结构体变量的成员多了一个指向下一个结构体变量的指针,

  • 题目要求输入的整数,在存入链表时是倒着存入的,也就是要用头插法,头插法也就是一直在头节点h后插入新节点q,主要代码为q->next=h->next; h->next=q;,拓展下,正着存入也就是尾插法,需要增加一个尾指针p,使其始终指向当前链表的尾结点,每插入一个新节点后让p指向这个新节点,主要代码为p->next=q; p=q;
  • 头节点只有指针域,没有数据域, 别看输入输出的规矩这么一大串,写4个if用strcmp函数比对字符串,看调用那个函数,

参考代码:

部分函数我用的是bool类型的,要加上#include<stdbool.h>,也可以用int类型,只要返回值有正确和错误的性质就好

先拆分开解释:

  1. 链表的定义:
typedef struct LNode{
    int data;//数据域
    struct LNode *next;//指针域
}LinkList;//定义结构体变量的别称,加个解引符*,*LinkList就是定义结构体指针的别称
  1. 创建链表:
void createList(LinkList *L,int n)//依照题目使用的是头插法
{
    LinkList *p,*q;
    p=L;//使p指向头节点
    //如果在main函数里已经L->next=NULL,就不用在这p->next=NULL,因为是头插法,所以赋空的操作应该在创建节点前,因为头插法没有指向尾节点的指针,尾插法的赋空操作在创建节点后
    for(int i=0;i<n;i++)//创建n个节点
    {
        q=(LinkList*)malloc(sizeof(LinkList));
        scanf("%d",&q->data);
        q->next=p->next;//把p节点后续的节点接在q节点后
        p->next=q;//再把q节点接在p节点后
    }
}
  1. 在第a个位置前面插入e:
bool insertList(LinkList *L,int a,int e)
{
    LinkList *p=L,*q;
    q=(LinkList*)malloc(sizeof(LinkList));
    q->data=e;//创建一节点存储e,该节点为要插入的节点
    while(a>1)//a>1是保证p在循环结束后指向第a-1个位置的节点
    {
        p=p->next;
        if(p==NULL)
        return false;
        a--;
    }
    q->next=p->next;//与头插法原理一样,把p节点后续的节点接在q节点后
    p->next=q;//把q节点接在p节点后
    return true;
}
  1. 获得第a个位置的元素,获取成功输出该位置上的元素
bool getList(LinkList *L,int a)
{
    LinkList *p=L->next;//此时p指向第一个节点,也就是如果a=1的话,即输出p节点的数据域
    while(a>1)//使p指向第a个位置的节点
    {
        p=p->next;
        if(p==NULL)
       {
        printf("get fail\n");
        return false;
       }
        a--;
    }
    
    printf("%d\n",p->data);
    return true;
}
  1. 删除第a个元素
bool deleteList(LinkList *L, int a)
{
    LinkList *p = L,*q=L->next;//p指向头节点,q指向第一个节点
    if(q==NULL)//判断链表是否为空
    return false;
    while(a>1)//p指向被删除节点的前一个结点,q指向要被删除节点
    {
        p=p->next;
        q=q->next;
        if(q==NULL)
        return false;
        a--;
    }
    p->next=q->next;//使p节点跳过q节点指向q节点的下一个节点
    free(q);//释放q节点占用的空间,也就是删除了
    return true;
}
  1. 输出链表中所有元素
bool displayList(LinkList *L)
{
    LinkList *p;
    p=L->next;
    if(p==NULL)//判断链表是否为空
    {
        printf("Link list is empty\n");
        return false;
    }
    while(p)//输出链表所有元素
    {
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
    return true;
}

以上就为题目用得上的功能函数了

整体代码:
为了main函数看得更美观点,做了些改动

#include<stdio.h>
#include<stdlib.h>//需要这个才能用malloc
#include<string.h>
#include<stdbool.h>//bool
typedef struct LNode{
    int data;
    struct LNode *next;
}LinkList;
void createList(LinkList *L,int n)
{
    LinkList *p,*q;
    p=L;
    
    for(int i=0;i<n;i++)
    {
        q=(LinkList*)malloc(sizeof(LinkList));
        scanf("%d",&q->data);
        q->next=p->next;
        p->next=q;
    }
   
}
bool getList(LinkList *L,int a)
{
    LinkList *p=L->next;
    while(a>1)
    {
        p=p->next;
        if(p==NULL)
        return false;
        a--;
    }
    
    printf("%d\n",p->data);
    return true;
}
bool insertList(LinkList *L,int a,int e)
{
    LinkList *p=L,*q;
    q=(LinkList*)malloc(sizeof(LinkList));
    q->data=e;
    
    while(a>1)
    {
        p=p->next;
        if(p==NULL)
        return false;
        a--;
    }
    q->next=p->next;
    p->next=q;
    return true;
}
bool deleteList(LinkList *L, int a)
{
    LinkList *p = L,*q=L->next;
    if(q==NULL)
    return false;
    while(a>1)
    {
        p=p->next;
        q=q->next;
        if(q==NULL)
        return false;
        a--;
    }
    p->next=q->next;
    free(q);
    return true;
}

bool displayList(LinkList *L)
{
    LinkList *p;
    p=L->next;
    if(p==NULL)
    return false;
    while(p)
    {
        printf("%d ",p->data);
        p=p->next;
    }
    printf("\n");
    return true;
}
int main()
{
	int n;
	scanf("%d",&n);
	LinkList *L;
	L=(LinkList*)malloc(sizeof(LinkList));
	L->next=NULL;
	createList(L,n);
	int m,a,e;
	char str[10];
	scanf("%d",&m);
	for(int i=0;i<m;i++)
	{
	    scanf("%s",str);
	    if(strcmp(str,"show")==0)//将所有操作失败时会输出的信息,放在这些if分支里
        {
            if(!displayList(L))
            printf("Link list is empty\n");
        }
	    else if(strcmp(str,"delete")==0)
	    {
	        scanf("%d",&a);
	        if(deleteList(L,a))
	        printf("delete OK\n");
	        else
	        printf("delete fail\n");
	        
	    }
	    else if(strcmp(str,"get")==0)
	    {
	        scanf("%d",&a);
	        if(!getList(L,a))
            printf("get fail\n");
	    }
	    else if(strcmp(str,"insert")==0)
	    {
	        scanf("%d%d",&a,&e);
	        if(insertList(L,a,e))
	        printf("insert OK\n");
	        else
	        printf("insert fail\n");
	        
	    }
	}
	return 0;
}

由于自己对于链表的学习也只是刚刚起步,有错的地方希望大家能够指正(。・ω・。)

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

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

相关文章

k8s 经常操作指令

发现有个技巧&#xff1a;get、describe、edit ...操作指令后&#xff0c;都对应的相应的资源类型/资源 编辑deployment&#xff0c;查看其中部署的容器 kubectl edit deploy -n namespace pod名前缀&#xff08;不带hash&#xff09; 注&#xff1a; 带hash的具体pod&…

如何让光猫4个网口都有网络

一般情况光猫只有LAN1口有网络&#xff0c;LAN2、LAN3和LAN4口都是预留给电视用的&#xff0c;那么如何让这3个网口也有网络呢&#xff1f; 使用场景&#xff1a; 光猫在弱电箱内&#xff0c;弱电箱中有三根网线&#xff08;网线1、网线2和网线3&#xff09;分别接入到了三个房…

IP地址与子网掩码

1 IP地址 1.1 IPv4与IPv6 1.2 IPv4地址详解 IPv4地址分4段&#xff0c;每段8位&#xff0c;共32位二进制数组成。 1.2.1 地址分类 这32位又被分为网络号和主机号两部分&#xff0c;根据网络号占用位数的不同&#xff0c;又可分为以下几类&#xff1a; A类地址&#xff1a;…

蓝桥杯(更新中)

递归与递推 递归 1.指数型枚举 解析&#xff1a;从 1 ∼ n 这 n 个整数中随机选取任意多个&#xff0c;输出所有可能的选择方案。 思路&#xff1a;枚举每一位对应的数字选与不选&#xff0c;例如&#xff1a;第一位对应的数字为1&#xff0c;有一种方案是选1&#xff0c;另…

解决报错——使用sqlite的扩展Spatialite

正文 笔者想使用sqlite3的扩展Spatiate 代码如下。 import sqlite3 conn sqlite3.connect(database.db) conn.enable_load_extension(True) conn.load_extension("mod_spatialite") 结果如下。 找不到指定模块。 笔者在网上到处搜索&#xff0c;终于解决了。&a…

电磁兼容(EMC):静电放电(ESD)抗扰度试验深度解读(一)

目录 1 .导言 2.适用产品范围 3.标准目的 4.试验等级 4.1 空气放电的最高电压为何定在15kV 1 .导言 电磁兼容设计的知识储备之一便是EMC相关标准&#xff0c;标准中的测试系统标准更是基础中的基础&#xff0c;深度理解&#xff0c;对产品的EMC设计有很好的帮助。以下对最…

算法题->盛最多水的容器C语言和JAVA双指针解法

盛最多水的容器C语言和JAVA双指针解法 题目描述: 力扣链接:https://leetcode.cn/problems/container-with-most-water/description/ 题意: 根据数组中的值(高)和下标差值(宽),求能容纳最多的体积V. 例子: 输出49的求解过程,根据木桶效应,存储水的高度由短木板决定,故 V 短…

EfficientVMamba实战:使用EfficientVMamba实现图像分类任务(一)

文章目录 摘要安装包安装timm 数据增强Cutout和MixupEMA项目结构编译安装Vim环境环境安装过程安装库文件 计算mean和std生成数据集 摘要 论文&#xff1a;https://arxiv.org/pdf/2401.09417v1.pdf 作者研究了轻量级模型设计的新方法&#xff0c;通过引入视觉状态空间模型&…

Linux中JMeter的使用

Linux中JMeter的使用 Linux版本JMeter安装 # 1、下载、安装JMeter 如果有安装包直接上传即可 wget -c https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-5.4.1.tgz # 解压 tar -zxvf apache-jmeter-5.4.1.tgz -C /usr/local/sjdwz_test cd /usr/local/sjdwz_t…

书生·浦语大模型全链路开源体系-第2课

书生浦语大模型全链路开源体系-第2课 书生浦语大模型全链路开源体系-第2课相关资源实战部署InternLM2-Chat-1.8B模型准备环境下载模型运行案例 实战部署InternLM2-Chat-7B模型准备环境下载模型及案例代码运行cli案例代码运行web案例代码配置SSH公钥信息配置SHH隧道连接 熟悉 Hu…

前端之CSS——网页的皮肤!!

目录 一、CSS简单介绍 二、css内容 2.1 css的编写方式 2.2 css选择器 2.3 样式属性 2.4 css包围盒 2.5 css中的display 2.6 css中的定位 2.7 css中的浮动与清除 2.7 弹性容器 2.8 字体图标 2.9 …

R语言,数据类型转换

原文链接&#xff1a;R语言技能 | 不同数据类型的转换 本期教程 写在前面 今天是4月份的第一天&#xff0c;再过2天后再一次迎来清明小假期。木鸡大家是否正常放假呢&#xff1f; 我们在使用R语言做数据分析时&#xff0c;会一直对数据进行不同类型的转换&#xff0c;有时候…

Linux安装nginx保姆级教程

文章目录 前言一、nginx安装&#xff08;保姆级教程&#xff09;1.安装nginx依赖2.安装wget3.创建nginx安装目录4.下载nginx5.查看下载好的nginx6.解压缩7.查看当前目录下的文件→进入nginx-1.8.0目录→查看当前目录下的文件8.安装nginx9.查看nginx安装目录并启动nginx10.网络请…

https安全性 带给im 消息加密的启发

大家好&#xff0c;我是蓝胖子&#xff0c;在之前# MYSQL 是如何保证binlog 和redo log同时提交的&#xff1f;这篇文章里&#xff0c;我们可以从mysql的设计中学会如何让两个服务的调用逻辑达到最终一致性&#xff0c;这也是分布式事务实现方式之一。今天来看看我们能够从http…

VTK中polydata的属性数据结构表示和用法

vtk中通过vtkDataArray进行数据的存储&#xff0c;通过vtkDataObject进行可视化数据的表达&#xff0c;在vtkDataObject内部有一个vtkFieldData的实例&#xff0c;负责对数据的表达&#xff1a; vtkFieldData存储数据的属性数据&#xff0c;该数据是对拓扑结构和几何结构信息的…

项目管理计划

《项目管理计划》 1.项目背景说明 2.项目目标和范围 3.项目组织架构 4.项目进度管理办法 5.项目沟通管理 6.项目风险管理 软件开发全套资料包获取进主页或文末个人名片直接获取。

Excel 数据-分列的三个经常用法

Case 1 &#xff1a;有时候数据导出时如果没有电子表格的话&#xff0c;只能导出本地文件&#xff0c;如下图情况&#xff1a; 可以使用数据-分列处理数据&#xff1a; 原来是因为SAP导出数据没有完成的原因&#xff0c;或者关闭Excel重新打开试一下。 重新打开后可以输入了 C…

日记本(源码+文档)

日记本&#xff08;小程序、ios、安卓都可部署&#xff09; 文件包含内容程序简要说明功能项目截图客户端首页日记列表 书写日记个人中心设置密码锁拨打客服热线修改信息退出登录登录页输入密码锁注册页 后端管理登录页首页管理员列表管理用户管理日记列表管理日记数据 文件包含…

2024年网络安全运营体系建设方案

以下是部分WORD内容&#xff0c;请您参阅。如需下载完整WORD文件&#xff0c;请前往星球获取&#xff1a; 网络安全运营监控工作整体构想 工作目标及原则 工作目标 为进一步落实强化公司网络安全保障&#xff0c;有效支撑公司数字化转型战略&#xff0c;建立健全公司网省两级协…

Tomcat调优总结

Tomcat自身的调优是针对conf/server.xml中的几个参数的调优设置。首先是对这几个参数的含义要有深刻而清楚的理解。以tomcat8.5为例&#xff0c;讲解参数。 同时也得认识到一点&#xff0c;tomcat调优也受制于linux内核。linux内核对tcp连接也有几个参数可以调优。 因此可以将…