单链表
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) +指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
如图是一个结点
多个结点加上head(头结点)指针(指向了第一个结点的位置)就构成了单链表,最后一个结点的Next指向了空,其中结点的数据存放并不是连续的,像数组那样,但是只要使用Next指针,一样可以达到逻辑上的连续
数组模拟
在这里我们用数组模拟单链表
首先当链表中还没有数据时,头结点应该指向空(NULL),如图
我们把空用数字-1来代替,因为数组中是没有-1下标的,所以最开始头结点指向了-1
void unit() //初始化链表
{
head = -1;
idx = 0;
}
好,那现在往链表中添加结点,但是这有两种情况,一种是在头结点后添加. 一种是往已有结点添加
我们先来实现第一种,我们添加的结点就要指向-1,因为他是链表中最后一个结点,那头结点就要存储我们这个结点的数组的下标,也就是这个结点的位置0,如图
void add_head(int x)
{
e[idx] = x; //存储的值
eo[idx] = head; //head最开始为-1
head = idx++; //head指向了 0
}
好,如果是第二种,往第k个结点后添加结点,第一个结点的下标为0,所以第k个结点的下标为k-1
如图
得
void add_k(int k, int x)
{
e[idx] = x;
eo[idx] = eo[k]; //这个结点指向了k结点指向的下一个结点的坐标
eo[k] = idx++; //k结点指向我们新添加的结点
}
将某一个结点删除,一是将头结点后的结点删除,二是将k结点后面的结点删除,不是真正的删除它在数组中的存在,而是链表中访问不到它了
来看第一种
void remove_head()
{
head = eo[head];
}
第二种
以上的添加和删除节点中的k,在传入参数时为原数据的-1,因为下标是从0开始的,而结点是从一开始
,如果传入时,传入的不是k-1,那么要在函数内对k--
好已经有了初始化链表函数,删除函数,添加结点函数,来道题
题目
代码
#include <iostream>
using namespace std;
const int N = 10010;
int e[N], eo[N];
int idx,head;
void unit()
{
head = -1;
idx = 0;
}
/*
void add_head(int x) //因为题目中插入的k是>0的,所以没有在头结点后插入这步操作
{
e[idx] = x;
eo[idx] = head;
head = idx++;
}
*/
void add_k(int k, int x)
{
e[idx] = x;
eo[idx] = eo[k];
eo[k] = idx++;
}
void remove_head()
{
head = eo[head];
}
void remove_k(int k)
{
eo[k] = eo[eo[k]];
}
int main(void)
{
unit();
int M;
cin >> M;
while (M--)
{
char op;
int k=0, x=0;
cin >> op;
if (op == 'H')
{
cin >> x;
add_head(x);
}
else if (op == 'D')
{
cin >> k;
if (!k)
{
remove_head();
}
else
{
remove_k(k - 1);
}
}
else
{
cin >> k >> x;
if (!k)
{
add_head(x);
}
else
{
add_k(k - 1, x);
}
}
}
//遍历链表
for (int i = head; i != -1;i=eo[i])
{
cout << e[i] << " ";
}
}