C++学习笔记#23(2021.6.9)

190 阅读1分钟

静态链表

昨天的问题在反反复复打断点debug之后终于解决了 错误代码:

#include <iostream>
using namespace std;

const int N = 100010;

int idx, head, e[N], ne[N];

//向链表头插入一个元素
void add_to_head(int x) {
    e[idx] = x;
    ne[idx] = head;
    head = idx++;
}

//删除第 k 个插入的数后面的数
void delete_after_k(int k) {
    ne[k] = ne[ne[k]];
}

//在第 k 个插入的数后插入一个数
void add_after_k(int x, int k) {
    e[idx] = x;
    ne[idx] = ne[k];
    ne[k] = idx++;
}

int main() {
    int head = -1;
    int idx = 0;
    int m;
    cin >> m;
    while (m--) {
        int k, x;
        char op;
        cin >> op;
        if (op == 'H') {
            cin >> x;
            add_to_head(x);
        }
        else if (op == 'D') {
            cin >> k;
            if (!k) head = ne[head];
            delete_after_k(k - 1);
        }
        else {
            int k, x;
            cin >> k >> x;
            add_after_k(x, k - 1);
        }
    }
    for (int i = head; i != -1; i = ne[i]) { 
        cout << e[i] << ' '; 
    }
    cout << endl;
    return 0;
}

乍看之下没什么问题,其实就出在链表初始化上面:

int main() {
    int head = -1;
    int idx = 0;
    int m;
    cin >> m;
    while (m--) {

改正:

int main() {
    head = -1;
    idx = 0;
    int m;
    cin >> m;
    while (m--) {

在最外层的定义域内我们定义了head和idx,这里本来要调用init函数,其实直接把-1赋给head和0赋给idx是一样的效果,错就错在不该再用int去定义它们,导致编译器认为这是个局部变量,虽然在main函数里面是head=-1,idx=0,但是当调用到add_to_head函数时,此时add_to_head函数定义域扩大了,就使用了开头的定义(默认值为0),导致初始化失败,head=0之后ne[idx]没有指向-1而是0,再导致后面一系列操作出错,最后ne[i]一直指向的是最开始加进去的头结点9,就会一直输出99999。

总结:在全局定义的变量,后面初始化的时候不要加类型,否则只在局部有作用。