为什么我的这段代码在OJ中出现runtime error?

KurumiKakako
  • 1
新手上路,请多包涵

题目描述

将1至n的自然数的某种排列记为P,将P中的数字P1,P2,...,Pn插入集合S(S中预先已经插入0和n+1)。每插入一个数字,输出当前S中比该数字小的数中的最大数以及比该数字大的数中的最小数。

案例:
输入:
5
1 5 2 4 3

输出:
0 6
1 6
1 5
2 5
2 4

题目来源及思路

来源:学习链表的数据结构后的练习作业
思路:把整个过程倒过来,先把0到n+1的数字按顺序放入链表,再把输入数据按输入顺序的倒序从链表中删除

相关代码

#include <iostream>
using namespace std;

class ListNode {
    
private:
    int data;
    ListNode *Lnext;
    ListNode *Rnext;
    
public:
    ListNode(int dataValue){
        data = dataValue;
        Lnext = NULL;
        Rnext = NULL;
    }
    
    //get
    int get_Data() {
        return data;
    }
    
    ListNode *get_LNext() {
        return Lnext;
    }
    
    ListNode *get_RNext() {
        return Rnext;
    }
    
    //set
    void set_LNext(ListNode *newnode) {
        Lnext = newnode;
    }
    void set_RNext(ListNode *newnode) {
        Rnext = newnode;
    }
    
};



class List {

private:
    ListNode* first;
    
public:
    List();
    List(int);
    void addNode(int);
    void deleteNode(int, int*);
};

List::List(){
    first = NULL;
}

List::List(int n) {
    for (int i=0; i<=(n+1); i++) {
        addNode(i);
    }
}

void List::addNode(int data) {
    
    ListNode *newnode = new ListNode(data);
    if (first == NULL) {
        first = newnode;
    }
    else {
        ListNode *p = first;
        while (p->get_RNext() != NULL) {
            p = p->get_RNext();
        }
        p->set_RNext(newnode);
        newnode->set_LNext(p);
    }
    
}

void List::deleteNode(int data, int* a) {
    
    ListNode *p = first;
    while (p->get_Data() != data) {
        p = p->get_RNext();
    }
    a[0] = p->get_LNext()->get_Data();
    a[1] = p->get_RNext()->get_Data();
    p->get_LNext()->set_RNext(p->get_RNext());
    p->get_RNext()->set_LNext(p->get_LNext());
}



int main() {
    
    int n;
    cin >> n;
    int *P = new int [n];
    for (int i=0; i<n; i++) {
        cin >> P[i];
    }
    
    List S(n);
    int** result = new int* [n];
    for (int i = 0; i<n; i++) {
        result[i] = new int [2];
    }
    for (int i=n-1; i>=0; i--) {
        S.deleteNode(P[i],result[i]);
    }
    
    for (int i=0; i<n; i++) {
        cout << result[i][0] << " " << result[i][1] << endl;
        delete [] result[i];
    }
    delete [] result;
    delete [] P;
    
    return 0;
}

看到的错误信息

题目中给出的测试案例我通过了没有问题,但是不知道为什么上传到OJ系统显示runtime error。

备注:本人小白,刚开始学习编程没多久,各方面都还在摸索,虚心求教。按照网上出现runtime error我看得懂的可能原因排查了半天还是找不出问题。求好心人解答(⑉꒦ິ^꒦ິ⑉) 谢谢!

回复
阅读 1.2k
1 个回答

TL;DR: 你定义了俩 List 构造函数,而有参数的那个中没有 first = NULL

修改后

#include <iostream>
using namespace std;

class ListNode {
public:
// private:
    int data;
    ListNode *Lnext;
    ListNode *Rnext;

// public:
    ListNode(int dataValue) {
        data = dataValue;
        Lnext = NULL;
        Rnext = NULL;
    }
    /*
    //get
    int get_Data() {
        return data;
    }

    ListNode *get_Lnext() {
        return Lnext;
    }

    ListNode *get_Rnext() {
        return Rnext;
    }

    //set
    void set_Lnext(ListNode *newnode) {
        Lnext = newnode;
    }
    void set_Rnext(ListNode *newnode) {
        Rnext = newnode;
    }
    */
    // 没看出这个 get/set 有啥用,你都 public 了
};


class List {
private:
    ListNode* first = NULL; // 可以直接在这设置默认值

public:
    List();
    List(int);
    void addNode(int);
    void deleteNode(int, int*);
};

// List::List(){
//     first = NULL; // 这里没被调用!
// }

List::List(int n) {
    // 或者在这
    // first = NULL;
    for (int i = 0; i <= n + 1; i++) addNode(i);
}

void List::addNode(int data) {
    cout << "add" << data << endl; 
    ListNode *newnode = new ListNode(data);
    if (first == NULL) {
        first = newnode; // 原本 addNode(0) 时没有进这里!
    }
    else {
        ListNode *p = first;
        while (p->Rnext != NULL) {
            p = p->Rnext;
        }
        p->Rnext = newnode;
        newnode->Lnext = p;
    }
}

void List::deleteNode(int data, int* a) {
    ListNode *p = first;
    while (p->data != data) {
        p = p->Rnext;
    }
    a[0] = p->Lnext->data;
    a[1] = p->Rnext->data;
    p->Lnext->Rnext = p->Rnext;
    p->Rnext->Lnext = p->Lnext;

    delete p;
}
int main() {
    const int max_n = 100;
    int n, P[max_n];
    // int *P = new int [n];
    // OI 中直接定最大范围是好习惯,就算考试中决定放弃大数据的点,
    // 一般来说也没必要动态生成。当然如果是在练习使用指针那当我没说。
    
    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> P[i];
    }

    List S(n);

    int result[max_n][2]; // 其实我觉得没必要存下答案吧
    // int** result = new int* [n];
    // for (int i = 0; i<n; i++) {
    //     result[i] = new int [2];
    // }

    for (int i = n - 1; i >= 0; i--) {
        S.deleteNode(P[i], result[i]);
    }

    for (int i = 0; i < n; i++) {
        cout << result[i][0] << " " << result[i][1] << endl;
        // delete [] result[i];
    }
    // delete [] result;
    // delete [] P;

    return 0;
}

/* I/O:
5
1 5 2 4 3


*/
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏