c++怎么可能是6564,1去哪里了?删除操作一共就3次,一共八个数,怎么可能最后剩下4个数字?

本文介绍了单链表的基本概念,以及如何用C和C++实现支持插入、删除操作的链表。特别强调了题目中的特殊情况——插入的序号不是链表的实际位置。展示了C++代码示例,并提出了C++输出结果与预期不符的问题分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链表题

1、用基本逻辑结构实现链表:

最简单的方式就是一个value和一个next指针,构成一个简单的单链表。但是在工作中不推荐使用,因为每次调用该结构都需要重新初始化一个链表,这将极大的影响算法的速度,可以提前初始化一定数量的链表,来防止速度方面问题的影响。

2、用数组模拟链表:

单链表最大的功能就是邻接表,作为存储图和树的基本结构。单链表可以用来写邻接表(包括n个链表),邻接表可以存储树和图,最短路问题、最小生成树问题、最大流问题都可以用邻接表来存储。

双链表的功能是优化某些问题。大话数据结构写到,为了克服单向性的弱点(如在单链表中国查找要从头开始,如果查的元素是最后一个,会极大的浪费时间),双向链表被设计出来,和单链表的区别是多了一个前驱指针。本质上是用空间来换时间,为某个结点的前后操作带来了便利。双向链表的缺点是,指针数的增加会导致存储空间需求增加;添加和删除数据时需要改变更多指针的指向。

单链表,存储的值为3、5、7、9,对于的next指针指向的元素位置为1,2,3,-1

\826. 单链表

题目,单链表

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

  1. 向链表头插入一个数;

  2. 删除第 k个插入的数后面的一个数;

  3. 在第 k 个插入的数后插入一个数。

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

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

输入格式

第一行包含整数 M,表示操作次数。

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

  1. H x,表示向链表头插入一个数 x。

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

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

输出格式

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

数据范围

1≤M≤10000 所有操作保证合法。

输入样例:
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

C语言

​
#include <stdio.h>
​
#define N 100010
​
int n;
int h[N], e[N], ne[N], head, idx;
​
void init(){
    head = -1;
    idx = 0;
}
​
void int_to_head(int x) {
    e[idx] = x;
    ne[idx] = head;
    head = idx;
    idx ++;
}
​
void add(int k, int x) {
    e[idx] = x;
    ne[idx] = ne[k];
    ne[k] = idx;
    idx ++;
}
​
void removek(int k) {
    if (k == 0) head = ne[head];
    else if (ne[k] != -1) ne[k] = ne[ne[k]];
}
​
int main() {
    init();
​
    scanf("%d", &n);
    char s;
    while(n--) {
        scanf(" %c", &s);
        if (s == 'H') {//在链表头插入
            int x;
            scanf("%d", &x);
            if (head == -1) {//判断是否为空
                head = idx;
                e[idx] = x;
                ne[idx] = -1;
                idx ++;
            } else {
                int_to_head(x);
            }
        }
        if (s == 'D') {//删除
            int k;
            scanf("%d", &k);
            removek(k - 1);//处理删除第k个数后面的数
        }
        if (s == 'I') {//插入
            int k, x;
            scanf("%d %d", &k, &x);
            add(k - 1, x);//处理插入第k个数后面
        }
        scanf("%c", &s);//读入换行符并丢弃
    }
​
    int i = head;
    while(i != -1) {
        printf("%d ", e[i]);
        i = ne[i];
    }
    printf("\n");
​
    return 0;
}

c++语言实现

#include <iostream>
using namespace std;
const int N = 100010;
// head 表示头结点的下标
// e[i] 表示节点i的值
// ne[i] 表示节点i的next指针是多少
// idx 存储当前已经用到了哪个点
int head, e[N], ne[N], idx;
// 初始化
void init()
{
    head = -1;
    idx = 0;
}
// 将x插到头结点
void add_to_head(int x)
{
    e[idx] = x, ne[idx] = head, head = idx ++ ;
}
// 将x插到下标是k的点后面
void add(int k, int x)
{
    e[idx] = x, ne[idx] = ne[k], ne[k] = idx ++ ;
}
// 将下标是k的点后面的点删掉
void remove(int k)
{
    ne[k] = ne[ne[k]];
}
int main()
{
    int m;
    cin >> m;
    init();
    while (m -- )
    {
        int k, x;
        char op;
        cin >> op;
        if (op == 'H')
        {
            cin >> x;
            add_to_head(x);
        }
        else if (op == 'D')
        {
            cin >> k;
            if (!k) head = ne[head];
            else remove(k - 1);
        }
        else
        {
            cin >> k >> x;
            add(k - 1, x);
        }
    }
    for (int i = head; i != -1; i = ne[i]) cout << e[i] << ' ';
    cout << endl;
    return 0;
}

疑问:

1、因为题干:注意:题目中第 k 个插入的数并不是指当前链表的第 k个数。例如操作过程中一共插入了 n个数,则按照插入的时间顺序,这 n 个数依次为:第 11 个插入的数,第 22 个插入的数,…第 n个插入的数。所以c语言写出和c++写出的运行结果不一样,c++是大佬写的,根据模拟数据

输入样例:
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

c语言输出的应该是6 4 6 5 1

c++输出的是6 4 6 5

根据我思考的逻辑

1、10

k序号0

2、H 9 插入头结点,9的k序号为1

9 10

1 0

3、I 1 1 把1插入到k序号为1的元素后面

9 1 10

1 2 0

4、D 1 删除k序号为1的元素

1 10

2 0

5、D 0 删除k序号为0的元素

1

2

6、H 6 头插值为6的元素,k序号为3

6 1

3 2

7、I 3 6 插入到k序号为3的元素后面,值为6

6 6 1

4 3 2

8、I 4 5插入到k序号为4的元素后面 ,值为5

6 5 6 1

4 5 3 2

9、I 4 5 插入到k序号为4的元素后面,值为5

6 5 5 6

4 6 5 3 2

10、I 3 4 插入到k序号为3的元素后面,值为4

6 5 5 6 4 1

4 6 5 3 7 2

11、D 6 删除k序号为6的元素

6 5 6 4 1

4 5 3 7 2

c++怎么可能是6564,1去哪里了?删除操作一共就3次,一共八个数,怎么可能最后剩下4个数字?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值