数组实现各类数据结构

目录

一、数组实现单链表

二、数组实现双链表

三、数组实现栈

四、数组模拟队列

五、数组模拟单调栈

六、数组模拟单调队列(滑动窗口)

七、数组模拟堆


一、数组实现单链表

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;
const int N=1e5+10;
int e[N],ne[N],q,head,idx;
//e[i]表示结点i的值
//ne[i]表示结点i的next的指针是多少
//idx存储当前已经用到了哪个点
void init()
{
    head=-1;
    idx=0;
    e[0]=0;
    ne[0]=0;
}
//将x插到head---插入操作
void add_to_head(int x)
{
    e[idx]=x,ne[idx]=head,head=idx,idx++;
}
//将x插到下标为k的点的后面
void add(int k,int x)
{
    e[idx]=x,ne[idx]=ne[k],ne[k]=idx,idx++;
}
//将下标是k的后面的点删掉
void remove(int k)
{
    ne[k]=ne[ne[k]];
}
#if 0
int main(void)
{
    cin>>q;
    while(q--)
    {
        int t;
        cin>>t;
        if(t==1)
        {
            int x,int y;
            cin>>x>>y;
        }
    }
    return 0;
}
#endif

二、数组实现双链表

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;
const int N=1e5+10;
int l[N],r[N],e[N],head,idx;
int n,m;

//初始化
void init()
{
    //0表示左端点 1表示右端点
    r[0]=1,l[1]=0;
    idx=2;
}
//在下标为k的右边插入x
//如果要实现在下标为k的左边插入x  直接调用add(l[k],x)
void add(int k,int x)
{
    e[idx]=x;
    r[idx]=r[k];
    l[idx]=k;
    l[r[k]]=idx;//这一步和下一步不可以颠倒
    r[k]=idx;
}
//删除第k个点
void remove(int k)
{
    r[l[k]]=r[k];
    l[r[k]]=l[k];
}

三、数组实现栈

B3614 【模板】栈 - 洛谷

cpp 复制代码
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e6+10;
#define int unsigned long long
int stk[N],tt;//tt表示栈顶下标
//1.插入一个元素:stk[++tt]=x;
//2.删除一个元素:tt--;
//3.判断栈是否为空:if(tt>0)
//4.栈顶元素:stk[tt];
signed main(void)
{
    int  t;
    cin>>t;

    while(t--)
    {
        int n;
        cin>>n;
        tt=0;
        for(int i=1;i<=n;i++)
        {
            string s;
            cin>>s;
            if(s=="push")
            {
                int x;cin>>x;
                stk[++tt]=x;
            }
            else if(s=="pop")
            {
                if(tt==0)cout<<"Empty"<<endl;
                else tt--;
            }
            else if(s=="query")
            {
                if(tt>0)cout<<stk[tt]<<endl;
                else cout<<"Anguei!"<<endl;
            }
            else if(s=="size")
            {
                cout<<tt<<endl;
            }
        }
    }
    return 0;
}

四、数组模拟队列

B3616 【模板】队列 - 洛谷

cpp 复制代码
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e4+10;
int hh,tt=-1,q[N];

//1.队尾插入一个元素:q[++tt]=x;
//2.弹出:hh++
//3.判断是否为空:if(hh<=tt)为空 else 非空
//4.取出队头元素:q[hh]
int main(void)
{
    int  t;
    cin>>t;
    while(t--)
    {
            int opt;
            cin>>opt;
            if(opt==1){
                int x;cin>>x;
                q[++tt]=x;
            }
            else if(opt==2)
            {
                if(hh>tt)cout<<"ERR_CANNOT_POP"<<endl;
                else hh++;
            }
            else if(opt==3)
            {
                if(hh>tt)cout<<"ERR_CANNOT_QUERY"<<endl;
                else cout<<q[hh]<<endl;
            }
            else if(opt==4)
            {
                cout<<tt-hh+1<<endl;
            }
        
    }
    return 0;
}

五、数组模拟单调栈

码蹄集OJ-山脉

cpp 复制代码
//求一段序列中的每个元素之前的第一个小于它的元素
#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;
const int N=3e6+10;
int n,stk[N],tt;
int main(void)
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        int x;
        cin>>x;
        while(tt&&stk[tt]>=x)tt--;
        if(tt)cout<<stk[tt]<<" ";
        else cout<<1<<" ";
        stk[++tt]=x;
    }
    return 0;
}

六、数组模拟单调队列(滑动窗口)

P1886 滑动窗口 /【模板】单调队列 - 洛谷

cpp 复制代码
#include<iostream>
#include<algorithm>
#include<cstring>

using namespace std;
const int N=1e6+10;
int q[N],a[N],n,k,tt=-1,hh=0;
int main(void)
{
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n>>k;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=1;i<=n;i++)
    {
        //判断队头是否已经滑出窗口 如果没滑出窗口 则hh++
        while(hh<=tt&&(i-k+1)>q[hh])
        {
            hh++;
        }
        //将队列中的元素与第i个元素进行比较,如果队列中的元素大于当前元素 则弹出
        while(hh<=tt&&a[q[tt]]>=a[i])
        {
            tt--;
        }
        q[++tt]=i;
        if(i>=k)cout<<a[q[hh]]<<" ";
       
    }
    cout<<endl;
    tt=-1,hh=0;
    for(int i=1;i<=n;i++)
    {
        //判断队头是否已经滑出窗口 如果没滑出窗口 则hh++
        while(hh<=tt&&(i-k+1)>q[hh])
        {
            hh++;
        }
        //将队列中的元素与第i个元素进行比较,如果队列中的元素大于当前元素 则弹出
        while(hh<=tt&&a[q[tt]]<=a[i])
        {
            tt--;
        }
        q[++tt]=i;
        if(i>=k)cout<<a[q[hh]]<<" ";
       
    }
    return 0;
}

七、数组模拟堆

cpp 复制代码
#include<iostream>
#include<algorithm>

using namespace std;
const int N=1e6+10;

int h[N],size;
void down(int u)
{
    int t=u;
    if(2*u<=size&&h[u*2]<h[t])t=u*2;
    if(u*2+1<=size&&h[u*2+1]<h[t])t=u*2+1;
    if(u!=t)
    {
        swap(h[u],h[t]);
        down(t);
    }
}
void up(int u)
{
   while(u/2>0&&h[u/2]>h[u])
   {
       swap(h[u/2],h[u]);
       up(u/2);
   }
}
void insert(int x)
{
    size++; h[size]=x;
    up(size);
}
void remove()
{
    h[1]=h[size],size--;
    down(1),up(1);
}
int main(void)
{
    int n;
    cin>>n;
    while(n--)
    {
        int op;
        cin>>op;
        if(op==1)
        {
            int x;
            cin>>x;
            insert(x);
        }
        else if(op==2)cout<<h[1]<<endl;
        else 
        {
            remove();
        }
    }
    return 0;
}