链表

我看了下其他人的wp,单链表维护一个呀把头节点会更好,双链表就是两个头尾。

单链表

image

这道题目做到吐血。一定要做好注释,不要把1和0都写不对。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;



int main()
{
    int m;
    int p;
    int v;
    int time=1;
    int idx;
    int workp=0;
    int head = 0;
    cin >> m;
    char opt;
    int K[100100]={0};
    int P[100100]={0};
    int V[100100]={0};
    int freeidx=1;//低级错误了,把0当成freeidx的开头了,现在好了

    //设置表头
    P[0] = -1; //0号位置是表头
    V[0] = 0; //0号位置的值是0
    while (m -- ){
        cin >> opt;
        if(opt=='H'){//在表头插入的意思是放在第一个,哎,不是在第一个后面插入,又看错了
            idx = freeidx++;
            cin >> v;
            P[idx] = P[0];
            V[idx] = v;
            P[0] = idx;
            K[time++] = idx;//记录对应次数和索引
        }else if(opt == 'D'){//注意是删除第k个数的后面的数不是第k个数。。无语了
            cin >> v;
            if(v==0){
                workp = P[head];
                P[head] = P[workp];
                P[workp] = 0;
                V[workp] = 0;
                continue;
            }//如果是0直接处理头
            //获取第k个插入的数的索引
            v = K[v];
            workp = P[v];
            //存储上一个头,把上一个头的下一个指针,指向workp的指针
            P[v] = P[workp];
            P[workp] = 0;
            V[workp] = 0;
        }else if(opt =='I'){
            int k;
            cin >> k >> v;
            workp = K[k];
            idx = freeidx++;
            P[idx] = P[workp];
            V[idx] = v;
            P[workp] = idx;
            K[time++] = idx;
        }
    }
    workp = P[head];
    while(workp!=-1){
        cout<<V[workp]<<" ";
        workp = P[workp];
    }
    return 0;
}


双链表

可写死我了,要注意不同的情况。打pwn做这种太ez

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;

struct link{
    int l;
    int r;
    int v;
};

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int times=1;
    int freeidx=0;
    int leftL = -2;
    int rightL = -2;
    int m;
    int v;
    int k;
    string opt;
    int workp = 0;
    cin >> m;
    vector<int> K(m+10,0);
    vector<link> L(m+10);//三位分别是左指针,右指针,值
    
    for (int i = 0; i < m; i ++ ){
        L[i].l=-2;L[i].r=-2;L[i].v=0;//-2是没有,-1是结束。
    }
    //注意被处理的块是在中间、两边、单独的情况
    while(m--){
        cin >> opt;
        if(opt=="L"){
            cin >> v;
            if(leftL==-2){//不存在最左边堆块,说明空链表,直接插入
                L[freeidx].l = -1;
                L[freeidx].r = -1;
                L[freeidx].v = v;
                leftL = freeidx;
                rightL = freeidx;
                K[times++] = freeidx++;
                continue;
            }
            //如果有直接在最左边插入
            L[freeidx].l=-1;
            L[freeidx].r = leftL;
            L[freeidx].v = v;
            L[leftL].l = freeidx;
            leftL = freeidx;
            K[times++] = freeidx++;
        }else if(opt=="R"){
          cin >> v;
          if(rightL==-2){
              L[freeidx].l=-1;
              L[freeidx].r=-1;
              L[freeidx].v=v;
              leftL = freeidx;
              rightL = freeidx;
              K[times++] = freeidx++;
              continue;
          }
          L[freeidx].r = -1;
          L[freeidx].l = rightL;
          L[freeidx].v = v;
          L[rightL].r = freeidx;
          rightL = freeidx;
          K[times++] = freeidx++;
        }else if(opt=="D"){
          cin >> v;
          workp = K[v];//获得当前索引
          if(leftL==workp&&rightL==workp){
            //只有我一个啊
            leftL = -2;
            rightL = -2;
            continue;
          }
          if(L[workp].l==-1){
            leftL = L[workp].r;
            L[L[workp].r].l = -1;//下一个的上一个变成他的上一个
            continue;
          }
          if(L[workp].r==-1){
            rightL = L[workp].l;
            L[L[workp].l].r = -1;//上一个堆块的下一个堆块变成他的下一个
            continue;
          }
          L[L[workp].l].r = L[workp].r;//上一个堆块的下一个堆块变成他的下一个
          L[L[workp].r].l = L[workp].l;//下一个的上一个变成他的上一个
         }else if(opt=="IL"){
           cin >> k >> v;
           //在K[k]的左边加上v
           workp = K[k];
           L[freeidx].r = workp;
           L[freeidx].l = L[workp].l;//新的块的左右指向对应的地方
           L[freeidx].v = v;
           L[workp].l = freeidx;//更新其下一个指向他
           if(L[freeidx].l==-1){
            leftL = freeidx;
           }else{
            L[L[freeidx].l].r = freeidx;//更新其上一个指向他
           }
           K[times++] = freeidx++;
         }else if(opt=="IR"){
           cin >> k >> v;
           //在K[k]的有右边加上v
           workp = K[k];
           L[freeidx].l = workp;
           L[freeidx].r = L[workp].r;//新的块的左右指向对应的地方
           L[freeidx].v = v;
           L[workp].r = freeidx;//更新其下一个指向他
           if(L[freeidx].r==-1){
            rightL = freeidx;
           }else{
            L[L[freeidx].r].l = freeidx;//更新其上一个指向他
           }
           K[times++] = freeidx++;
      }
    }
    workp = leftL;
    while(workp!=-1&&workp!=-2){
        cout << L[workp].v << " ";
        workp = L[workp].r;
    }
    return 0;
}

posted @ 2025-07-24 20:20  .N1nEmAn  阅读(8)  评论(0)    收藏  举报