《算法基础》数组模拟链表、栈和队列

《算法基础》数组模拟链表、栈和队列


前言

为什么要用数组来模拟链表,栈和队列那?  这些不是在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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Coder_小庞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值