AcWing
  • 首页
  • 题库
  • 题解
  • 分享
  • 问答
  • 活动
  • 应用
  • 吐槽
  • 登录/注册

AcWing 826. 单链表    原题链接    简单

作者: 作者的头像   wuog ,  2019-08-06 01:30:24 ,  阅读 5219


42


11

题目描述

实现一个单链表,链表初始为空,支持三种操作:

(1) 向链表头插入一个数;

(2) 删除第k个插入的数后面的数;

(3) 在第k个插入的数后插入一个数

现在要对该链表进行M次操作,进行完所有操作后,从头到尾输出整个链表。

注意:题目中第k个插入的数并不是指当前链表的第k个数。例如操作过程中一共插入了n个数,则按照插入的时间顺序,这n个数依次为:第1个插入的数,第2个插入的数,…第n个插入的数。

输入格式
第一行包含整数M,表示操作次数。

接下来M行,每行包含一个操作命令,操作命令可能为以下几种:

(1) “H x”,表示向链表头插入一个数x。

(2) “D k”,表示删除第k个输入的数后面的数(当k为0时,表示删除头结点)。

(3) “I k x”,表示在第k个输入的数后面插入一个数x(此操作中k均大于0)。

输出格式
共一行,将整个链表从头到尾输出。

数据范围
1≤M≤100000
所有操作保证合法。

样例

输入样例:
10
H 9
I 1 1
D 1
D 0
H 6
I 3 6
I 4 5
I 4 5
I 3 4
D 6
输出样例:
6 4 6 5

算法1

时间复杂度分析:链表在插入的时候可以达到O(1)的复杂度

理解

int head, e[N], ne[N], idx;

// 初始化
void init()
{
    head = -1;
    idx = 0;
}

// 在链表头插入一个数a

void insert(int a)
{
    e[idx] = a, ne[idx] = head, head = idx ++ ;
}

捕获1.PNG

解释一下 就先把值赋到数据域,然后让head的地址值存入指针域,让idx向下移一位;

//向表中k位置插图x

void add(int k,int x){
    n[idx]=x;
    ne[idx]=ne[k];
    ne[k]=idx++;
}

捕获2.PNG

// 将k删除,需要保证头结点存在

void remove(int k)
{
    ne[k]=ne[ne[k]];

}

这个与插入思想类似:
捕获4.PNG

C++ 代码

#include<iostream>
using namespace std;
const int N=100010;
int idx,head,n[N],ne[N];
int a;
void add_head(int x){
    n[idx]=x;
    ne[idx]=head;
    head=idx++;
}
void add(int k,int x){
    n[idx]=x;
    ne[idx]=ne[k];
    ne[k]=idx++;
}
void remove(int k){
    ne[k]=ne[ne[k]];
}

int main(){

    head=-1;idx=0;
    cin>>a;
    while(a--){
        string op;
        int k,x;
        cin>>op;
        if(op=="D")
        {

            cin>>k;
            if(!k)head=ne[head];
            remove(k-1);
        }
        else if(op=="H")
        {
            cin>>x;
            add_head(x);
        }
        else if(op=="I"){
            int k,x;
            cin>>k>>x;
            add(k-1,x);
        }
    }
    for(int i=head;i!=-1;i=ne[i])
      cout<<n[i]<<" ";
    return 0;

}

22 评论


用户头像
Charon_96   14天前     回复

i为什么是等于-1的时候退出循环啊

用户头像
wuog   14天前     回复

这个问题可以具象化一下,head==-1时就到头了,表示结束,注意我们刚开始对于head的初始的值!哈哈哈哈·


用户头像
dfbdberberb   10个月前     回复

请问为什么删除头结点之后 不直接coninue呢?
$ ne[-1]=ne[ne[-1]]; $这个操作为什么下表为-1但是没有越界呢?
麻烦好哥哥抽出时间解答下我多年的疑惑

用户头像
wuog   10个月前     回复

这个我去思考一下

用户头像
Anish   8个月前     回复

C++ 有时会允许下标为负,但是最好不要这样写,加个特判吧

用户头像
zyc2004   7个月前    回复了 Anish 的评论     回复

下标代表地址,如果ai是可访问的

用户头像
tqyue   6个月前    回复了 Anish 的评论     回复

对,还是加上特判为好,不加continue在java里无疑会出错


用户头像
cdd_1   11个月前     回复

if(!k)head=ne[head];删除判断,为什么k为0,头结点都只会在0吗

用户头像
Anish   8个月前     回复

题目说了, $k = 0$ 时删除头结点,与结点下标无关

用户头像
xswlhahaha   5个月前    回复了 Anish 的评论     回复

if(!k)head=ne[head];
remove(k-1);

不应该写成

if(!k)head=ne[head];
else remove(k-1);

吗?

用户头像
Anish   5个月前    回复了 xswlhahaha 的评论     回复

不是啊,这个if是特判,一般情况下都要执行remove啊

用户头像
xswlhahaha   5个月前    回复了 Anish 的评论     回复

这个if是特判,当k==0时,执行head=ne[head];就是相当于在执行remove.
而不加else的话,当k==0时remove()不就执行了两次咯?

用户头像
Anish   5个月前    回复了 xswlhahaha 的评论     回复

啊,你说的对,我去看了眼我自己的代码,确实有else

用户头像
pporappippam   13天前    回复了 xswlhahaha 的评论     回复

如果执行2次,那不就remove(-1),head前面还有东西嘛
怎么有没有都没得影响啊
盖亚.


用户头像
喜欢吃鱼   2020-02-29 10:42     回复

为什么是用数组来模拟链表,这样不是得开辟连续的内存空间吗,为什么不用指针呢?背离链表存在的意义了呀

用户头像
wuog   2020-03-01 23:39     回复

这里的链表是一种抽象的数据结构,每个节点有信息和下一个节点的地址,和怎么实现半毛钱关系也没有。链表当然也可以用数组实现,也可以用STL的vector,都不用动态allocate。
对于指针,我们来看一下静态域动态的区别:
数组静态分配内存,链表动态分配内存;
数组在内存中连续,链表不连续;
数组元素在栈区,链表元素在堆区;
数组利用下标定位,时间复杂度为O(1),链表定位元素时间复杂度O(n);
数组插入或删除元素的时间复杂度O(n),链表的时间复杂度O(1);

用户头像
喜欢吃鱼   2020-03-02 00:51    回复了 wuog 的评论     回复

是的,我俩说的不一样,代码这里说的链表是逻辑上的,是依赖数组实现的。我说的链表是直接操作内存、地址不连续的存储结构,之前学C的时候,我写链表都是用struct{ int val; Node* next;} 这样写。。。你这里说的是一种逻辑结构,不关心它是如何实现的,我明白了,多谢啦。

用户头像
jasonlin   11个月前     回复

Y总说 数组来模拟静态链表不容易超时, new一个node花费的时间很容易超时~
所以做题时用 数组来模拟 静态链表~

用户头像
RiCharZh   46分钟前     回复

单链表

单链表在算法竞赛或者在笔试里最常用的作用就是写邻接表,邻接表的作用是存储树和图

这里单链表我们用数组模拟,也可以采用结构体模拟;后者更好理解但是在算法竞赛中出于对效率的考虑,我们用数组模拟单链表(以及后续的所有数据结构)

当然也可以使用C++或是Java自带的单链表,但是这些效率都不如数组高

这里实现的单链表又叫静态链表,写工程的时候常用动态链表


用户头像
王子涵   2020-02-16 02:31     回复

删除头结点的那一块不明白,删除操作为啥要保证头节点存在啊

用户头像
wuog   2020-02-16 06:22     回复

他要有一个索引值

用户头像
王子涵   2020-02-16 06:35    回复了 wuog 的评论     回复

ok,谢谢,看双链表的时明白了,索引的意义

你确定删除吗?

© 2018-2021 AcWing 版权所有  |  京ICP备17053197号-1
联系我们  |  常见问题
AcWing
请输入登录信息
更多登录方式: 微信图标 qq图标
请输入绑定的邮箱地址
请输入注册信息