我有一个作业,我需要从用户那里输入一个输入字符串,然后使用该字符串中的字符填充一个双向链接列表。这意味着我需要遍历用户字符串并生成一个双向链接列表。我创建了一个for循环,并且输出正常,但是显示输出后我的程序立即崩溃。我总共有2周的C ++经验,所以请原谅我的菜鸟错误。在下面找到代码。

#include<cstdlib>
#include<iostream>
#include <string>

using namespace std;

struct node {
    string data;
    node *next;
    node *prev;
};

string getString() {
    string userString;
    cout << " Please enter a string for reversal: ";
    cin >> userString;
    return userString;
}

// print forward
void printDataFor(node* head);
// print reverse
void printDataRev(node* tail);

int main() {
    node* head= new node;
    node* tail= new node;
    node* n;
    string reverse = getString();
    int length = reverse.length();

    // loop to create linked list
    for (int i = 0; i < length - 1; i++) {
        if (head->prev == NULL) {
            n = new node;
            n->data = reverse[i];
            n->prev = NULL;
            head = n;
            tail = n;
        }
        else {
            n = new node;
            n->data = reverse[i];
            n->prev = tail;
            tail->next = n;
            tail = n;
        }
    }

    n = new node;
    n->data = reverse[length-1];
    n->prev = tail;
    tail->next = n;
    tail = n;
    tail->next = NULL;
    // call to print reverse
    printDataRev(tail);
}

// print forward
void printDataFor(node* head) {
    node* temp = head;
    while (temp != NULL) {
        cout << temp->data;
        temp = temp->next;
    }
}

// print reverse
void printDataRev(node* tail) {
    node* temp = tail;
    while (temp != NULL) {
        cout << temp->data;
        temp = temp->prev;
    }
}

最佳答案

显示的代码中存在多个错误。

node* head= new node;

// ...

if (head->prev == NULL) {


您期望新构造的节点将具有prevnext指针初始化为NULL。

这是一个非常合理的期望。问题是您的代码中没有什么可以做到的:

struct node {
    string data;
    node *next;
    node *prev;
};


如果没有显式构造函数,new不会将nextprev初始化为任何东西。它们将是垃圾,显示的代码可能会在某个时候尝试取消引用垃圾指针,从而导致崩溃。

您需要一个显式的构造函数,以将它们初始化为NULL(或使用当前C ++标准中引入的新语法,并为它们两个声明默认的初始化程序)。

这是第一个问题。

第二个问题是,出于某些无法解释的原因,对主for循环进行了编码,使其迭代次数比所需次数少,并且有重复的代码块将最后一个值插入到链表中。我看不出为什么需要这样做。只需遍历所有字符,然后将其插入即可。

第三个问题是逻辑似乎会在链表中插入一个额外的headtail节点,其数据将为空字符串。从外观上看,不会有任何可见的效果,因为打印链接列表的循环只会打印一个空字符串。不过,从技术上讲这是错误的。

您需要调整逻辑以消除重复的虚假节点。首先将headtail初始化为NULL,而不是初始化new(通常无用)节点:

node *head=NULL;
node *tail=NULL;


然后相应地调整for循环中的逻辑,以测试字符串中第一个字符的边缘条件,这将构造一个新节点,同时headtail都指向该节点,并执行常规执行路径在head之前插入每个后续字符。

关于c++ - C++使用For循环创建双链表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39442248/

10-11 22:40
查看更多