时间复杂度分别为 O(n)和 O(1)的删除单链表结点的方法
有一个单链表,提供了头指针和一个结点指针,设计一个函数,在 O(1)时间内删除该结点指针指向的结点。
众所周知,链表无法随机存储,只能从头到尾去遍历整个链表,遇到目标节点之后删除之,这是最常规的思路和做法。

如图所示,删除结点 i,那么只需找到 i 的前驱 h,然后连 h 到 j,再销毁i 即可。虽然可以安全的删除 i 结点,但是是顺序查找找到 i,之后删除,时间复杂度是 O(n)级别的。具体做法就是:顺序查找整个单链表,找到要删除结点 i 的直接前驱 h,把 h额 next 指向i 的 next ,再删除 i 结点即可
现在假设的是我们知道这个单链表里一定存在我们需要删除的结点(也就是存在目标结点),因为是单链表,结点没有前驱,那么找到前驱,我们只能从头结点开始扫描整个链表,那么,我们可不可以去找到要删除结点的下一个结点呢?
时间复杂度为 O(1)的删除单链表结点的方法
如果我们直接找到要删除结点的下一个结点,是非常方便的,不用去遍历整个链表,只需把删除结点 i 的下一个结点j 的内容复制到 i 上,然后把 i 的指针指向 j 的next,然后再删除j 结点。等价于删除了 i 结点。整个过程无需遍历整个链表,时间复杂度是 O(1)级别
继续思考这个思路:这个方法,依靠的是结点的后继指针,如果要删除的结点在末尾,也就说,结点没有后继,怎么处理?
本题目没有给出尾指针,那么此种特殊情况,还是需要从头到尾遍历整个链表,得到该结点的前驱,然后删除该结点。
继续思考,如果单链表只有一个结点,那么删除该结点需要做什么处理?
如果单链表只有一个结点,现在需要删除这个结点,也就是链表的头结点(尾结点),那么在删除之后,需要把头指针指向 NULL处理。
代码实现如下:
typedef struct Node{
int data;
Node *next;
} Node, *List;
void deleteNode(List *head, Node *del)
{
Node *p = NULL;
//判断链表是否为空
if (!head) {
cout << "链表为空!" << endl;
exit();
}
//如果删除的结点是尾结点
if (del->next == NULL) {
p = *head;
//仍然需要遍历链表
while (p->next != del) {
//顺次后移
p = p->next;
}
//找到前驱,断链
p->next = NULL;
//删除结点
delete del;
//预防野指针
del = NULL;
}
//如果单链表只有一个结点
else if(*head == del){
//无需断链,直接删除
delete del;
del = NULL;
//头指针处理
*head = NULL;
}
//如果链表里有多个结点,且删除的结点不是尾结点
else{
//无须遍历链表
p = del->next;
del->data = p->data;
del->next = p->next;
delete p;
p = NULL;
}
}
时间复杂度分析:
如果是删除非末位的结点,且结点有n(n>1)个,那么时间复杂度是 o(1),对于尾结点,是 o(n),总得来说,是【(n-1)o(1)+o(n)】/ n,结果还是 o(1),复合要求。
注意
1、考虑问题要全面,不要丢三落四,以为出了结果,就算完成任务了。需要严谨的求学问。
2、这个题目的思路其实是建立在客户事先知道本链表里存在需要删除的结点。如果不知道,我们还是需要先遍历整个链表进行查找!那样时间复杂度还是 o(n)。
3、关于删除结点,往往都是只能想到找到前驱,删除,但是逆向思路看,不一定说,删除结点,就一定要删除这个结点,我们可以找到结点的后继,然后通过内容复制,删除该结点的后继结点,来达到删除该结点一样的效果。
欢迎关注
dashuai的博客是终身学习践行者,大厂程序员,且专注于工作经验、学习笔记的分享和日常吐槽,包括但不限于互联网行业,附带分享一些PDF电子书,资料,帮忙内推,欢迎拍砖!

时间复杂度分别为 O(n)和 O(1)的删除单链表结点的方法的更多相关文章
- 删除单链表节点,时间复杂度为O(1)
一个编程练习,删除单链表一个节点,且时间复杂度控制在O(1)内. 1.核心操作代码如下: struct ListNode { int m_data; ListNode *m_pNext; }; voi ...
- 用O(1)的时间复杂度删除单链表中的某个节点
给定链表的头指针和一个结点指针,在O(1)时间删除该结点.链表结点的定义如下: struct ListNode { int m_nKey; ListNode* m_pNext; }; 函数的声明如下: ...
- 数据结构(C语言第2版)----时间复杂度和单链表
马上要到校招了,复习下相关的基础知识. 时间复杂度是什么? 官方解释: 算法的执行时间需要依据算法所编制的程序在计算机上于运行时所消耗的时间来度量.在算法中可以使用基本的语句的执行次数作为算法的时间复 ...
- 单链表的回文判断(O(n)时间复杂度和O(1)的空间复杂度)
对于单链表来说,判断回文最简单的方法就是遍历链表,将链表中的元素复制到数组中,然后对数组进行判断是否是回文数组,但是这不符合O(1)的空间复杂度. 由于空间复杂度的要求,需要就地操作链表,不能开辟多余 ...
- 在O(n) 时间复杂度,O(1)空间复杂度内反转单链表
在LeetCode中看到判断回文的程序:https://leetcode.com/problems/palindrome-linked-list/ 里面用单链表来存储数据,先反转前半部分的单链表,然后 ...
- 感觉单链表是实现BCL ICollection 的最佳方式,所有操作都能以最小的时间复杂度完成
public interface ICollection<T> : IEnumerable<T>, IEnumerable { int Count { get; }// ...
- C# - 集合类
C#的集合类命名空间介绍: // 程序集 mscorlib.dll System.dll System.Core.dll // 命名空间 using System.Collections:集合的接口和 ...
- 《数据结构》2.3单链表(single linked list)
//单链表节点的定义 typedef struct node { datatype data; struct node *next; }LNode,*LinkList; //LNode是节点类型,Li ...
- C#栈
线性表.栈和队列这三种数据结构的数据元素以及数据元素间的逻辑关系完全相同,差别是线性表的操作不受限制,而栈和队列的操作受到限制.栈的操作只能在表的一端进行, 队列的插入操作在表的一端进行而其它操作在表 ...
随机推荐
- 在ASP.NET Core中使用百度在线编辑器UEditor
在ASP.NET Core中使用百度在线编辑器UEditor 0x00 起因 最近需要一个在线编辑器,之前听人说过百度的UEditor不错,去官网下了一个.不过服务端只有ASP.NET版的,如果是为了 ...
- JS里面Data日期格式转换
var format = function(time, format){ var t = new Date(time); var tf = function(i){return (i ...
- Ubuntu 16.10 安装byzanz截取动态效果图工具
1.了解byzanz截取动态效果图工具 byzanz能制作文件小,清晰的GIF动态效果图,不足就是,目前只能通过输入命令方式来录制. byzanz主要的参数选项有: -d, --duration=SE ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(55)-Web打印
系列目录 前言 1.本次主要弥补工作流,用户表单数据的打印 2.使用JQprint做为web打印插件 3.兼容:FireFox,Chrome,IE. 4.没有依赖也没有配置,使用简单 代码下载:htt ...
- 零OCR基础6行代码实现C#验证码识别
这两天因为工作需要,要到某个网站采集信息,一是要模拟登陆,二是要破解验证码,本想用第三方付费打码,但是想想网上免费的代码也挺多的,于是乎准备从网上撸点代码下来,谁知道,撸了好多个都不行,本人以前也没接 ...
- vmware上网的方式
vmware上网设置 vmware虚拟机上网设置 我的一些心得,如下: 如何使vmware虚拟机中的操作系统能够上网? 第一种情况: 主机使用PPPOE拨号上网 方法一:NAT方式 1.先关闭虚拟机中 ...
- 步入angularjs directive(指令)--准备工作熟悉hasOwnProperty
在讲解directive之前,先做一下准备工作,为何要这样呢? 因为我们不是简单的说说directive怎么用,还要知道为什么这么用!(今天我们先磨磨刀!). 首先我们讲讲js 基础的知识--hasO ...
- 基于注解的bean配置
基于注解的bean配置,主要是进行applicationContext.xml配置.DAO层类注解.Service层类注解. 1.在applicationContext.xml文件中配置信息如下 &l ...
- 关键帧动画:@keyframes
关键帧动画:@keyframes: <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...
- SharePoint2016安装的过程的”Microsoft.SharePoint.Upgrade.SPUpgradeException”错误解决方法
前提 在windows server 2012的服务器上运行安装sharepoint2016出现如下错误: Could not load file or assembly ‘Microsoft.Dat ...