前言:
用指针结构体来构建链表有两点不好:
- 代码长且复杂,容易出bug且不容易找到bug
- 使用new或者malloc,运算时间长,效率低
因此,使用数组来模拟链表!
1.模拟单链表
#include<iostream>
using namespace std;
const int N = 100010;
int head;//表示头节点的下标
int e[N]; //e[i]表示节点i的值
int ne[N]; //ne[i]表示节点i的下一个节点的下标
int idx; //元素下标,每个元素对应一个下标
void Init()
{
head = -1; //-1表示空节点
idx = 0;
}
void Insert(int x) //思路是将插入元素成为新的头节点,头节点后移一个单位
{
e[idx] = x; //新开一个节点
ne[idx] = head; //新节点的下一个节点是头节点,这一步实际上就是将原头节点变成新节点的下一个节点了。(相当于插入节点变成头节点,原头节点变成第二个节点)
head = idx; //新节点变成头节点
idx++; //节点指针加1,
}
void del(int x) //将x后面的一个元素删除
{
if (ne[x] == -1) //当前节点就是最后一个点,不能删除
return;
ne[x] = ne[ne[x]]; //x的下一个节点修改为下一个节点的下一个节点。就相当于把x的下一个节点跳过了
}
void Insert(int x,int k) //将x插入下标为k的元素的后面
{
e[idx] = x;
ne[idx] = ne[k];
ne[k] = idx;
idx++;
}
int main()
{
//(1)初始化,(2)插入元素,(3)删除元素,(4)修改元素
Init();
int x;
for(int i=0;i<10;i++) //将0-9插入链表
Insert(i);
cout << "输出单链表:";
for (int i = head; i != -1; i = ne[i])
{
int t = e[i];
cout << t << " ";
}
cout << endl;
//删除元素
cout << "删除元素:" << endl;
for (int i = 0; i < 5; i++) //删除下标i后面的一个元素
del(i);
for (int i = head; i != -1; i = ne[i])
{
int t = e[i];
cout << t << " ";
}
cout << endl;
//插入元素
cout << "插入元素:" << endl;
//注意,删除的只是在逻辑上删除,实际还存储在e数组里。所以只能插入到存在的元素后面
Insert(1000, 7);
for (int i = head; i != -1; i = ne[i])
{
int t = e[i];
cout << t << " ";
}
cout << endl;
return 0;
}
2.模拟双链表
#include<iostream>
#include<cstring>
using namespace std;
const int N = 100010;
int le[N]; //当前节点左边的节点
int re[N]; //当前节点右边的节点
int e[N];
int idx;
//该模板很有特点的一点是设置了两个哑节点,充当边界的作用
void Init()
{
re[0] = 1;
le[1] = 0;
idx = 2;
}
void Insert(int k,int x) //在下标k后面插入元素x
{
e[idx] = x;
re[idx] = re[k];
le[idx] = k;
re[k] = idx;
le[re[idx]] = idx;
idx++;
}
void remove(int k) //删除第k个插入的数
{
re[le[k]] = re[k];
le[re[k]] = le[k];
}
int main()
{
int n;
cin >> n;
Init();
while (n--)
{
string c;
cin >> c;
if (c =="L")
{
int x;
cin >> x;
Insert(0, x); //在左边头位置插入元素
}
else if (c == "R") //链表最右端插入元素
{
int x;
cin >> x;
Insert(le[1],x);
}
else if (c == "D") //删除第k插入的数,第一个插入的数的下标是2,0和1充当双链表的边界,不能动
{
int x;
cin >> x;
remove(x+1);
}
else if (c == "IL")//第k个插入的数左侧插入一个数
{
int x, k;
cin >> k >> x;
Insert(le[k+1], x);
}
else
{
//在第k个节点后插入一个数
int x, k;
cin >> k >> x;
Insert(k + 1, x);
}
}
int pos = re[0];
while (pos != 1)
{
cout << e[pos] << " ";
pos = re[pos];
}
return 0;
}