链表与邻接表
应用都可以用英文
为什么要用数组模拟
- 效率原因
- new Node(); // 非常慢,不会使用动态链表的形式
- 十万个节点会超时
- 如果直接初始化n个节点其实也是可以的
单链表
解题思路:
最主要还是理解三个操作:
- add
- remove
- add_to_head
数组实现的链表可以实现指针链表的所有事情.模拟的链表是静态的链表
用数组模拟邻接表
除非是找值,否则直接能找到位置
单链表只往后看,不能往前看。删了一个点就当它不存在就好了
idx只是一个地址。不用管删去的问题
TLE用删代码法
不会出现删除一个已经删除的点
可以先不管视频里怎么说的,一般来说,如果想删除链表第一个节点,会说“删除头结点”,如果想删除整个链表,会直接说“删除整个链表” head
是指向头结点的指针,它本身是不存节点的,只是指向了整个链表的第一个节点。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e5 +10;
int head, idx;
int ne[maxn], e[maxn];
void init()
{
head = -1;
idx = 0;
}
// 把某个值加入到头节点当中
void add_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 remove(int k)
{
ne[k] = ne[ne[k]];
// 不需要free
}
int main()
{
int m;
cin >> m;
while(m--)
{
char op;
cin >> op;
if(op == 'H')
{
int x;
cin >> x;
if(!x) head = ne[head];
add_to_head(x);
}
else if(op == 'D')
{
int k;
cin >> k;
remove(k - 1);
}
else
{
int k, x;
cin >> k >> x;
add(k - 1, x);
}
}
for(int i = head; i != -1; i = ne[i]) cout << e[i] << " ";
cout << endl;
return 0;
}
双链表
双链表的操作
-
add
注意我们是从idx = 2 开始运行的
-
remove
写成数组比较简单,比写成结构体数组要简单很多
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e5 + 10;
int k, x;
int head, tail, idx;
int l[maxn], r[maxn];
int e[maxn];
void init()
{
head = 0, tail = 1;
r[head] = 1;
l[tail] = 0;
idx = 2;
}
void add(int k, int x)
{
e[idx] = x;
l[idx] = k;
r[idx] = r[k];
l[r[k]] = idx;
r[k] = idx++;
}
void remove(int k)
{
l[r[k]] = l[k];
r[l[k]] = r[k];
//l[r[k]] = l[k];
// 不用idx--,地址放在那里不管就好了
}
void read()
{
string op;
cin >> op;
if(op == "L")
{
cin >> x;
add(head, x);
}
else if(op == "R")
{
cin >> x;
add(l[tail], x);
}
else if(op == "D")
{
cin >> k;
remove(k + 1);
}
else if(op == "IL")
{
cin >> k >> x;
add(l[k + 1], x); // l已经表示在左边了,不需要再-1
}
else if(op == "IR") // 两个字符的时候不能判断'r'
{
cin >> k >> x;
add(k + 1, x);
}
}
int main()
{
int m;
init(); // 不能每次都init
cin >> m;
while (m -- )
{
read();
}
for(int i = r[head]; i != tail; i = r[i]) printf("%d ", e[i]);
cout << endl;
return 0;
}
邻接表
邻接表就是n个单链表
链式前向星,就是数组模拟邻接表
模拟出来之后能更深刻的理解这个是在干嘛的
有什么问题可以加qq:1281372141进行交流