《算法基础》数组模拟链表、栈和队列
前言
为什么要用数组来模拟链表,栈和队列那? 这些不是在STL中都有吗 ?
其实一句话, 最主要的原因就是快。
一. 数组模拟单链表
源代码:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int head, idx; //head指向头结点的下标, idx为当前要用到的下标
int e[N], ne[N]; //e[i]为结点i的值, ne[i]结点i的next指针
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) //在k位置的后面,插入x
{
e[idx] = x;
ne[idx] = ne[k];
ne[k] = idx;
idx ++;
}
void remove(int k) //删除k位置后面的点
{
ne[k] = ne[ne[k]];
}
int main()
{
init();
int n;
cin >> n;
while (n --) {
char c;
int k, x;
cin >> c;
if (c == 'H') {
cin >> x;
add_to_head(x);
}
if (c == 'D') {
cin >> k;
if (!k) head = ne[head];
remove(k - 1);
}
if (c == 'I') {
cin >> k >> x;
add(k - 1, x);
}
}
for (int i = head; i != -1; i = ne[i]) {
cout << e[i] << " ";
}
cout << endl;
return 0;
}
二. 数组模拟双链表
源代码:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int e[N], l[N], r[N];
int idx;
void init()
{
r[0] = 1; l[1] = 0; idx = 2;
}
void add(int k, int x) //在k位置的右边插入x 左边插入为add(l[k], x);
{
r[idx] = r[k];
l[idx] = k;
l[r[k]] = idx;
r[k] = idx;
}
void remove(int k) //删除k位置的结点
{
r[l[k]] = r[k];
l[r[k]] = l[k];
}
int main()
{
return 0;
}
三. 数组模拟栈和队列
源代码:
#include <iostream>
#include <algorihtm>
using namespace std;
const int N = 100010;
//--------------------------------- 栈
int stack[N], tt; //top 初始值为0 表示空
stack[++ tt] = x; //插入
tt --; //删除
if (tt > 0) return false; // 判断是否为空
x = stack[tt]; //取栈顶元素
//--------------------------------- 队列
int q[N], tt = -1, hh = 0; //hh为队头指针, top初始值为 -1 为队尾指针,队头弹出, 队尾插入
q[++ tt] = x; //插入
hh ++; //删除
if (hh <= tt) return false; // 判断是否为空
x = q[hh];
int main()
{
return 0;
}
四. 列题:单调栈和单调队列
这些题型都有一个共同的特点, 就是经过一定的数据优化之后, 数据呈现单调的性质。
单调栈:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int stack[N], tt;
int n;
int main()
{
cin >> n;
for (int i = 0; i < n; i ++) {
int x;
cin >> x;
while(tt && stack[tt] >= x) tt --;
if (tt) {
cout << stack[tt] << " ";
} else {
cout << "-1" << " ";
}
stack[++ tt] = x;
}
return 0;
}
单调队列:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1000010;
int n, k;
int a[N], q[N];
int main()
{
cin >> n >> k;
for (int i = 0; i < n; i ++) scanf("%d", &a[i]);
int hh = 0, tt = -1;
for (int i = 0; i < n; i ++) {
if (hh <= tt && i - k + 1 > q[hh]) hh ++;
while (hh <= tt && a[q[tt]] >= a[i]) tt --;
q[++ tt] = i;
if (i - k + 1 >= 0) printf("%d ", a[q[hh]]);
}
cout << endl;
hh = 0, tt = -1;
for (int i = 0; i < n; i ++) {
if (hh <= tt && i - k + 1 > q[hh]) hh ++;
while (hh <= tt && a[q[tt]] <= a[i]) tt --;
q[++ tt] = i;
if (i - k + 1 >= 0) printf("%d ", a[q[hh]]);
}
return 0;
}