算法基础课:线性结构

1:链表,顾名思义,就是一个向链子一样套在一起的结点,对于每个结点,分为地址和数据两个块,在算法竞赛中我们常常使用静态链表(数组模拟链表)
也就是说对于链表我们什么时候使用这个数据结构呢?
通常情况下,我们对于需要频繁插入和删除的数据结构我们才会使用链表,因为此时对于插入和删除的时间复杂度是O(1)对于链表个人感觉感觉用的最多的地方还是在于邻接表和哈希里。
下面讲讲静态链表:

在这里插入代码片#include<cstdio>
#include<iostream>
using namespace std;
const int max1=1000010;
int e[max1],ne[max1],head=-1,idx=0;;
void ahead(int x)
{
e[idx]=x,ne[idx]=head,head=idx++;
}
void insert(int k,int x)
{
e[idx]=x,ne[idx]=ne[k],ne[k]=idx++;    
}
void remove(int k)
{
ne[k]=ne[ne[k]];
}

之后再讲双向链表:
双向链表本质上来说是一个双链表和双指针的头尾问题,特别需要注意。
对于一个节点来说,有两个指针,同时对于双链表来说,有左指针和右指针,特别注意的是插入和删除的顺序!

在这里插入代码片#include<cstdio>
#include<iostream>
using namespace std;
const int max1=1000010;
int e[max1],l[max1],r[max1],idx=0;
void init()
{
r[0]=1;
l[1]=0;
idx=2;
}
void insert(int k,int x)
{
e[idx]=x;
l[idx]=k;
r[idx]=r[k];
l[r[k]]=idx;
r[k]=idx;
}
void shanchu(int k)
{
l[r[k]]=l[k];
l[r[k]]=r[k];
}

注意这里插入有右插和左插,但是对于第K个点左插相当于对第K-1个点进行右插。然后还要注意这里初始化的时候,应该是一个利用了0和1两个点。
栈和队列:
对于栈来说用数组模拟实现:
有压栈,弹栈,判空,
取栈顶元素。
单调栈:
1:栈内元素单调递增或者是递减
2:对于递增栈,每次入一个元素,若比当前栈顶元素小,则不停出栈,直到找到比其小的值。(所以应用可以得到是判断元素大小)原理:
举个例子:
比如说有1 5 2 6 8 3 5 2 4
对于4来说要找到左边第一个比其小的元素,
我们可以得到,比如说对于3来说,其左边出现的比它大的数字,必然不是答案,所以这就是单调递增栈的应用。
同理对于递减栈:
对于3左边比其小的值必然不是答案
单调递减栈: ①在一个队列中针对每一个元素从它右边寻找第一个比它大的元素
②在一个队列中针对每一个元素从它左边寻找第一个比它大的元素(从后往前遍历)增小减大

在这里插入代码片#include<cstdio>
#include<iostream>
using namespace std;
const int max1=100010;
int main()
{
 int a[max1];
 int top=0;
 判空:if(top==0) 
 入栈: a[++top]=e;
 出栈:top--;
 提取栈顶元素:e=a[top]; 
}

队列:
单调队列:滑窗:

在这里插入代码片
#include<cstdio>
#include<iostream>
using namespace std;
const int a[max1];
int main()
{
int front,rear;
求队长:rear-front;
入队:a[rear++]=e; 
出队:front++;
提取队头元素:e=a[front]; 
提取队尾元素:e=a[rear-1]; 
}
``
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值