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)在链表头插入一个数
e[idx] = x; //将下标为idx的结点的值存入e数组
ne[idx] = head; //将下标为idx的结点的指针指向head原本的指向。
head = idx; //head指针指向第一位元素,不再指向空地址。
idx ++; //指针后移,为一下次做准备。
(3)在第k个数后插入一个数
e[idx] = x; //先将元素存进去
ne[idx] = ne[k]; //让元素x的指针指向所占元素的下一个位置
ne[k] = idx; //让上一个位置的指针指向自己
idx ++; //指针后移,为下一次做准备
(4)删除第k个插入的数后面的数
删除较为简单,将k指向 下一位的下一位,中间的哪一位就被挤掉了。
ne[k] = ne[ne[k]];
(5)总代码(附图理解)
#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…