单链表数组模拟

189 阅读2分钟

1.链表基本概念

  1. 概念:链表是一种物理存储结构上非连续、非顺序的存储结构,但链表在逻辑上是连续的,顺序的,而数据元素的逻辑顺序是通过链表中的指针连接次序实现的。

链表可以用结构体和数组来模拟。个人认为数组模拟更易为接受,因此本篇文章采用数组模拟。

2.链表是由一个个结点组成的,而每个结点有两部分。一部分存放该结点的数据,另一部分存放下一个结点的地址(用于实现两个结点的连接)

2.单链表实现

(1)初始化

定义4个变量。e[N], ne[N], idx, head; e数组表示链表中每一个元素的值,ne数组表示其所对应的值下一个结点的地址,idx表示所用到的数,head表示头结点的地址。 最开始链表里没有数,head指向-1,表示空链表。 idx = 0。

void init()
{
    head = -1;
    idx = 0;
}

(2)在链表头插入一个数

image.png

e[idx] = x;       //将下标为idx的结点的值存入e数组
ne[idx] = head;   //将下标为idx的结点的指针指向head原本的指向。
head = idx;       //head指针指向第一位元素,不再指向空地址。
idx ++;           //指针后移,为一下次做准备。

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

image.png

e[idx] = x;       //先将元素存进去
ne[idx] = ne[k];  //让元素x的指针指向所占元素的下一个位置
ne[k] = idx;      //让上一个位置的指针指向自己
idx ++;           //指针后移,为下一次做准备

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

删除较为简单,将k指向 下一位的下一位,中间的哪一位就被挤掉了。

ne[k] = ne[ne[k]];

(5)总代码(附图理解)

image.png

#include <iostream>

using namespace std;

const int N = 100010;
int head, e[N], ne[N], idx;

void init()
{
    head = -1;
    idx = 0;
}

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

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

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

int main()
{
    init();
    int m;
    cin >> m;

    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;
}

题目来自Acwing:www.acwing.com/problem/con…