数组模拟(一)
写在前面
近期的学习重点要放在图论了,之前一直在acwing中学习的数据结构都是数组模拟,数组模拟的效率比上stl要快上几倍,学完过后不久就会忘记,但是忘记也是一种学习,原本准备放弃数组模拟直接上stl要轻松的多,可是图论又得用到大量的数组模拟,最后还是打算攻坚克难把数组模拟各种数据结构给啃下来。(除此之外还能用来装*ヾ(•ω•`)o)
数组模拟(一)
单链表
// head 表示头节点
// e[N]用来存储每个节点的值
// ne[N]存储每个节点指向的下一个节点
// idx用来动态开辟空间或者理解为当前操作的位置
int head, e[N], ne[N], idx;
// 初始时head指向空节点,这里的-1即为空节点
void init()
{
head = -1;
}
// 向头节点的后一位插入节点
void add_to_head(int x)
{
e[idx] = x; // 先将该节点的值赋值给待插入的节点idx
ne[idx] = head; // 再将待插入节点的next指针指向head指向的节点
head = idx ++; // 最后改head指向待插入的这个节点
}
// 在第k个插入的元素后面插入节点
void add(int k, int x)
{
e[idx] = x; // 同理先赋值
ne[idx] = ne[k]; // 然后将待插入节点的next指针指向第k个节点指向的节点
ne[k] = idx ++; // 改变k的指向
}
// 删除第k个插入的元素后面的节点
void remove(int k)
{
// 让 k -> next 消失
ne[k] = ne[ne[k]]; // k -> next = k -> next -> next
}
双链表
// 双链表既可以知道前一个节点也可以知道后面一个节点
// l[N]数组表示左边的节点,r[N]表示后面一个节点
int e[N], idx, l[N], r[N];
void init()
{
l[1] = 0, r[0] = 1; // 左边的边界是0, 右边的边界是1
idx = 2; // 0,1都被占用了,这里idx就从2开始
}
// 在k节点的后面插入一个节点
void add(int k, int x)
{
e[idx] = x; // 先赋值
r[idx] = r[k], l[idx] = k; // 待插入节点的左指针指向k,右指针指向k指向的节点
// 下面改变原链表的顺序,注意下面的顺序
// 先把k的节点的左边指向idx,然后把k右指针指向待插入节点
l[r[k]] = idx, r[k] = idx ++;
}
// 删除k节点
void remove(int k)
{
r[l[k]] = r[k];
l[r[k]] = l[k];
}
int main()
{
// 遍历
for(int i = r[0]; i != 1; i = r[i])
cout << e[i] << ' ';
return 0;
}
模拟栈
实现一个栈,栈初始为空,支持四种操作:
push x– 向栈顶插入一个数 x;pop– 从栈顶弹出一个数;empty– 判断栈是否为空;query– 查询栈顶元素
#include <iostream>
using namespace std;
int stk[N], tt; // tt表示栈顶
int main()
{
string op; // 操作
int x; // 值
cin >> op;
if (op == "push")
{
cin >> x;
stk[++tt] = x;
}else if (op == "pop")
{
// 出栈,下次入栈时该位置上的值会被覆盖
tt--;
}
else if (op == "empty")
{
// 栈空tt为0
cout << (tt == 0 ? "YES" : "NO") << endl;
}else
{
// 查看栈顶元素
cout << stk[tt] << endl;
}
}
模拟队列
实现一个队列,队列初始为空,支持四种操作:
push x– 向队尾插入一个数 x;pop– 从队头弹出一个数;empty– 判断队列是否为空;query– 查询队头元素。
#include <iostream>
using namespace std;
// hh表示队头,tt表示队尾,之所以初始化为-1是因为入栈时tt会先自增
int q[N], hh, tt = -1;
int main()
{
string op;
int x;
cin >> op;
if (op == "push")
{
cin >> x;
q[++tt] = x; // 队尾自增
}else if (op == "pop")
{
hh ++; // 抛弃队头
}else if (op == "empty")
{
// 当tt == hh 时刚好有一个元素的时候,当队头自增时tt < hh,此时没有元素
cout << (tt >= hh ? : "NO" : "YES") << endl;
}else
{
// 输出队头元素
cout << q[hh] << endl;
}
}

浙公网安备 33010602011771号