数据结构--单链表的插入删除

数据结构–单链表的插入&删除

目标
单链表的插入(位插、前插、后插)
单链表的删除

单链表的插入

按为序插入(带头结点)

ListInsert(&L,i,e):插入操作。在表L中的第i个位置上插入指定元素e。

思路:找到第i-1个结点,将新结点插入其后

代码实现

typedef struct LNode
{ElemType data;  struct LNode *next; 
}LNode, *LinkList;bool ListInsert(LinkList &L, int i, ElemType e)
{if (i < 1)  return false;LNode *p = L; //L指向头结点,头结点是第0个结点(不存数据)int j = 0; //当前p指向的是第几个结点while (p != NULL && j < i - 1) //循环找到第i-1个结点{p = p->next;j++;}if (p == NULL)  return false;LNode* s = (LNode*)malloc(sizeof(LNode));s->next = p->next;s->data = e;p->next = s;return true;
}

时间复杂度

最好时间复杂度 O(1)
最坏时间复杂度 O(1)
平均时间复杂度 O(1)

按位序插入(不带头结点)

思路:找到第i-1个结点,将新结点插入其后

代码实现

typedef struct LNode
{ElemType data;  struct LNode *next; 
}LNode, *LinkList;bool ListInsert(LinkList &L, int i, ElemType e)
{if (i < 1)  return false;if (i == 1) //插入第1个结点的操作与其他结点操作不同{LNode* s = (LNode*)malloc(sizeof(LNode));s->data = e;s->next = L;L = s;return true;}LNode *p = L; //L指向头结点,头结点是第0个结点(不存数据)int j = 0; //当前p指向的是第几个结点while (p != NULL && j < i - 1) //循环找到第i-1个结点{p = p->next;j++;}if (p == NULL)  return false;LNode* s = (LNode*)malloc(sizeof(LNode));s->next = p->next;s->data = e;p->next = s;return true;
}

结论:
不带头写代码更不方便,推荐用带头结点
注意:考试中带头、不带头都有可能考察,注意审题

指定结点的后插操作

代码实现
typedef struct LNode
{ElemType data;struct LNode *next;
}LNode, *LinkList;bool InsertNextNode(LNode* p, ElemType e)
{if (p == NULL)  return false;LNode* s = (LNode*)malloc(sizeof(LNode));if (s == NULL)  return false; // 内存分配失败s->data = e;s->next = p->next;p->next = s;return true;
}

指定结点的前插操作

前插操作:在p结点之前插入元素e
bool InsertPriorNode (LNode *p,ElemType e)

方法一:
bool InsertPriorNode (LinkListL L, Node *p,ElemType e)
传入头指针,循环查找p的前驱,再对q后插
时间复杂度:O(n)

方法二 \color{red}方法二 方法二

方法二实现代码

typedef struct LNode
{ElemType data;struct LNode *next;
}LNode, *LinkList;bool InsertPriorNode (LNode *p,ElemType e)
{if (p == NULL)  return false;LNode* s = (LNode*)malloc(sizeof(LNode));if (s == NULL)  return false;s->next = p->next;p->next = s; //新结点s连到p之后s->data = p->data; //将p中元素复制到s中p->data = e; //p 中元素覆盖为ereturn true;
}

时间复杂度: O(n)

前插操作:在p结点之前插入结点 s

代码实现
bool InsertPriorNode(LNode* p, LNode* s)
{if (p == NULL || s == NULL) return false;s->next = p->next;p->next = s;ElemType tmp = p->data;p->data = s->data;s->data = tmp;return true;
}

单链表的删除

按位序删除(带头结点)

ListDelete(&L,i,&e):删除操作。删除表L中第i个位置的元素,并用e返回删除元素的值。

方法:
找到第i-1个结点,将其指针指向第i+1个结点,并释放第i个结点

代码实现

typedef struct LNode
{ElemType data;struct LNode *next;
}LNode, *LinkList;bool ListDelete(LinkList &L, int i, ElemType &e)
{if (i < 1)  return false;LNode *p = L;int j = 0;while (p != NULL && j < i - 1){p = p->next;j++;}if (p == NULL)  return false;if (p->next == NULL)    return false; //第i-1个结点之后已无其他结点LNode* q = p->next;e = q->data; //用e返回元素的值p->next = q->next; //将*q结点从链中“断开"free(q); //释放结点的存储空间return true;
}

时间复杂度:O(n)

删除指定结点p

bool DeleteNode ( LNode *p)

方法1:传入头指针,循环寻找p的前驱结点
时间复杂度O(n)
方法2:偷天换日(类似于结点前插的实现)
时间复杂度O(1)

方法二代码实现
typedef struct LNode
{ElemType data;struct LNode *next;
}LNode, *LinkList;bool DeleteNode(LNode* p)
{if (p == NULL)  return false;LNode* q = p->next; //令q指向*p的后继结点p->data = p->next->data; //和后继结点交换数据域p->next = q->next; //将*q结点从链中"断开"free(q);return true;
}

注: \color{red}注: 注:
如果 p 是最后一个结点,只能从表头开始依次寻找 p 的前驱 , 时间复杂度 O ( n ) \color{red} 如果p是最后一个结点,只能从表头开始依次寻找p的前驱,时间复杂度O(n) 如果p是最后一个结点,只能从表头开始依次寻找p的前驱,时间复杂度O(n)

知识点回顾与重要考点

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

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

相关文章

SpringMVC

SpringMVC常用注解: 1&#xff1a;Controller:用于标记控制器类&#xff0c;表示该类是可以处理HTTP请求的。 2&#xff1a;RequestMapping:用于映射URL和处理方法。可以在类和方法上&#xff0c;类级别的RequestMapping会对其中所有的方法进行URL映射。参数支持Ant-style路径…

01.网络编程-基础概念

网络编程就是指编写互联网项目&#xff0c;项目可以通过网络传输数据进行通讯 网络编程最主要的工作就是在发送端把信息通过规定好的协议进行组装包&#xff0c;在接收端按照规定好的协议把包进行解析&#xff0c;从而提取出对应的信息&#xff0c;达到通信的目的 1.1 软件结构…

掌握GDB调试工具,轻松排除bug!

一、什么是GDB gdb是GNU debugger的缩写&#xff0c;是编程调试工具。 GDB官网&#xff1a; https://www.gnu.org/software/gdb/GDB适用的编程语言&#xff1a; Ada / C / C / objective-c / Pascal 等。GDB的工作方式&#xff1a; 本地调试和远程调试。 目前release的最新版…

PG系列4:linux下编译安装PG15

文章目录 一. 源码安装1.1 下载并解压1.2 安装依赖包1.3 开始编译安装1.4 创建用户1.5 创建目录及修改权限1.6 设置环境变量1.7 初始化数据库1.8 启动和关闭数据库 二. 验证2.1 查看数据库后台进程2.2 验证和登陆数据库2.3 查看数据库版本2.4 查看数据库运行状态2.5 修改白名单…

Docker 安装 Redis

一、官方推荐安装方式&#xff1a; 1、执行 docker pull redis:4.0.1 命令&#xff0c;下载 redis 镜像&#xff0c;如下所示&#xff1a; 2、执行命令&#xff0c;创建并启动 redis 容器 docker run --rm -d --name redis6379 -p 6379:6379 redis:4.0.1 --requirepass "…

【QT】如何自定义QMessageBox的窗口大小,通过继承QDialog重新实现美观的弹窗

目录 1. QMessageBox原有的弹窗2. 网上第一种方法&#xff1a;通过样式表setStyleSheet实现改变弹窗大小&#xff08;总体不美观&#xff09;3. 网上第二种方法&#xff1a;重写ShowEvent()改变弹窗大小&#xff08;总体也不美观&#xff09;4. 最好的办法&#xff1a;继承QDia…

webstorm2022 TS1109: Expression expected.

在使用webstorm2022&#xff0c;加入ESLint&#xff08;已禁用&#xff09;的情况下&#xff0c;编写vue3的typescript代码时&#xff0c;报错&#xff1a; TS1109: Expression expected. 原因&#xff1a;2022版本不支持volar&#xff0c;需升级到2023版本。 官方描述为&am…

IAM风险CTF挑战赛

wiz启动了一个名为“The Big IAM Challenge”云安全CTF挑战赛。旨在让白帽子识别和利用 IAM错误配置&#xff0c;并从现实场景中学习&#xff0c;从而更好的认识和了解IAM相关的风险。比赛包括6个场景&#xff0c;每个场景都专注于各种AWS服务中常见的IAM配置错误。 Challenge…

Linux下vim的常见命令操作(快速复查)

目录 前言1、Vim常用操作1.1、环境参数1.2、方向1.3、插入命令1.4、定位命令1.5、删除命令1.6、复制和剪切命令1.7、替换和取消命令1.8、搜索和搜索替换命令1.9、保存和退出命令1.10、其他命令1.11、可视模式 前言 本篇文章不面向新手&#xff0c;全文几乎都是命令&#xff0c;…

使用python编程数学建模-常见excel数据使用python以行的方式按需读取

读取原始数据 首先导入pandas库   接着使用pandas库里面的read_csv方法来读取我们的文件&#xff0c;由于数据文件和程序文件是在统一目录下&#xff0c;因此无需使用绝对路径 import pandas as pd data1 pd.read_csv("data1.csv")读取数据的前20行数据 这里我们…

Java Web HTMLCSS(1)23.6.29

HTML&CSS 1&#xff0c;HTML 1.1 介绍 HTML 是一门语言&#xff0c;所有的网页都是用HTML 这门语言编写出来的&#xff0c;也就是HTML是用来写网页的&#xff0c;像京东&#xff0c;12306等网站有很多网页。 这些都是网页展示出来的效果。而HTML也有专业的解释 HTML(Hy…

【软件测试】Java+selenium环境搭建

目录 1.下载Chrome浏览器&#xff0c;查看浏览器的版本 2.根据浏览器版本下载驱动 根据电脑版本下载驱动&#xff1a; 3.去maven仓库寻找selenium驱动 4.在idea中创建一个项目 1.在pom.xml中添加依赖 2.点击右侧刷新按钮 3.在Java下创建一个类Main 4.将以下代码写入 5.…