OVSolitario-io

导航

链表的逻辑

链表

插入:

  • 先改新加入
  • 再改不知道的结点(如x)
  • 再改知道的结点(如y,z)

链表all逻辑操作都可以以这个顺序依次判断

截屏2025-09-09 19.43.58

删除:
同理,此时无新加入,不知道的点为y,z,即删除了x

定义数组模拟:lst[],nxt[]数组记录我的前驱后继

定义头结点
node[0].nxt = 1;
node[1].pre = 0, node[1].nxt = 0, node[1].val = 1;
//其中node[1].nxt = 0记录尾巴,即程序结束点
//遍历
for (int i = node[0].nxt; i != 0; i = node[i].nxt) cout << node[i].val << ' ';

两种遍历都是直接跑我下一个是谁,当我的下一个不是尾巴即过渡到下一个继续往后看

点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n, m, k, p, nxt[N], isInQueue[N], lst[N];
int main() {
    cin >> n;
    nxt[0] = 1;
    isInQueue[1] = 1;
    for(int i = 2; i <= n; ++ i) {
        isInQueue[i] = 1;
        cin >> k >> p;
        
        if(!p) {//插左边
            nxt[lst[k]] = i;
            lst[i] = lst[k];
            lst[k] = i;
            nxt[i] = k;
        }
        else {//插右边
            lst[nxt[k]] = i;
            nxt[i] = nxt[k];
            nxt[k] = i;
            lst[i] = k;
        }
    }
    cin >> m;
    for(int i = 1; i <= m; ++ i) {
        int x;
        cin >> x;
        if(!isInQueue[x]) continue;
        isInQueue[x] = 0;
        //去掉这个同学
        int t = lst[x];
        nxt[lst[x]] = nxt[x];
        lst[nxt[x]] = t;
        
    }
    //遍历链表
    int now = nxt[0];
    while(now != 0) {
        cout << now << ' ';
        now = nxt[now];
    }
    cout << endl;
}

结构体记录:

定义头结点
nxt[0] = 1;
nxt[1] = 0;//记录尾巴
//遍历链表
int now = nxt[0];
    while(now != 0) {
    cout << now << ' ';
    now = nxt[now];
}
点击查看代码
#include <bits/stdc++.h>
using namespace std;
struct Node{
    int val, pre, nxt;
};
Node node[1000010];
int n, m, x, y;

void push(int x, int k, int p) {//将i插入k的left,right✅
    node[x].val = x;
    if(p == 0) {//left
        //处理前面
        node[x].pre = node[k].pre;
        node[node[k].pre].nxt = x;
        
        node[x].nxt = k, node[k].pre = x;
    }
    else {//right
        //处理后面
        node[node[k].nxt].pre = x;
        node[x].nxt = node[k].nxt;
        
        node[x].pre = k, node[k].nxt = x;
        
    }
}
void pop(int x) {//✅
    node[x].val = -1;
    node[node[x].pre].nxt = node[x].nxt;
    node[node[x].nxt].pre = node[x].pre;
}


int main() {
    cin >> n;
    // node[0].nxt = 1, node[1].pre = 0;//❌
    node[0].nxt = 1;
    node[1].pre = 0, node[1].nxt = 0, node[1].val = 1;   // 记得把 val 也设上
    
    for(int i = 2; i <= n; ++ i) {
        cin >> x >> y;
        // cout << i << ' ' << x << ' ' << y << endl;
        push(i, x, y);//值,插在谁旁边
    }
    cin >> m;
    while(m -- ) {
        cin >> x;
        if(node[x].val == -1) continue;
        pop(x);
    }
    
    // for(int i = -1; i != 0; i = node[i].nxt) cout << node[i].val << endl;//❌
    for (int i = node[0].nxt; i != 0; i = node[i].nxt) cout << node[i].val << ' ';
    return 0;
}

为什么会有两种初始化头结点?
数组仅取记录位置,没有存我val值,而结构体开了个三元组,且nxt[1] = 0记录尾巴节点为了防止结点遍历出错,而正确的弹出

posted on 2025-09-09 19:49  TBeauty  阅读(6)  评论(0)    收藏  举报