基础算法笔记3
单链表
-
链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是存放指向下一个节点的指针域,最后一个节点的指针域指向null(-1)。
-
单链表的作用是用来创建邻接表,用于存储树和图。
-
用数组模拟链表,e[N]存放节点的值,ne[N]存放指向下一个节点的指针,head为头节点初始化为-1(表示链表结尾的空指针),idx表示当前用到哪个节点,即将要插入点的下标。
-
链表初始化,插入节点,删除节点的图示如下
-
对应的实现代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int e[N],ne[N],idx,head;
//初始化
void init(){
idx=0;
head=-1;
}
//插入头节点
void addhead(int x)
{
e[idx]=x;
ne[idx]=head;
head=idx++;
}
//在下标为k的点后插入x
void addx(int k,int x)
{
e[idx]=x;
ne[idx]=e[k];
ne[k]=idx++;
}
//删除下标为k的点后面的点
void remove(int k)
{
ne[k]=ne[ne[k]];
}
//删除头节点
void removehead()
{
head=ne[head];
}
双链表
-
不同于单链表,双链表每个节点有两个指针域,既可以向后查询也可以向前查询。
-
同样是用数组来模拟,e[N]表示节点的值,l[N]表示节点的左指针,r[N]表示节点的右指针,初始化时用0表示头节点,1表示尾节点,idx为尾指针,初始化为2.
-
初始化,插入与删除图示
-
对应代码实现
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int e[N],r[N],l[N],idx;
//初始化
void init(){
r[0]=1;
l[1]=0;
idx=2;
}
//向节点k右边插入x
void insertr(int k,int x)
{
e[idx]=x;
r[idx]=r[k];
l[idx]=k;
l[r[k]]=idx;
r[k]=idx++;
}
//向节点k左边插入x
void insertl(int k,int x)
{
insertr(l[k],x);
}
//删除k节点
void remove(int k)
{
l[r[k]]=l[k];
r[l[k]]=r[k];
}
栈(数组模拟)
-
栈(stack)是一种只允许在一端进行插入或删除的先进后出的线性表。
-
tt表示栈顶
int stk[N],tt=0;
-
栈顶插入数x(push)
stk[++tt]=x;
-
栈顶弹出(pop)
tt--;
-
查询栈顶(query)
stk[tt];
-
判断栈是否为空(empty)
if(tt>0)not empty; else empty;
队列
-
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表。队列是一种先进先出的线性表,简称FIFO。允许插入的一端称为队尾,允许删除的一端称为队头。
-
hh表示队头,tt表示队尾
int q[N],hh=0,tt=-1;
-
向队尾插入x(push)
q[++tt]=x;
-
队头弹出(pop)
hh++;
-
查询队头(query)
q[hh];
-
判断队空(empty)
if(hh<=tt)not empty; else empty;