我有一个赋值,我需要从用户那里获取一个输入字符串,然后使用字符串中的字符填充双向链表。这意味着我需要遍历用户字符串并生成双向链表。我创建了一个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;
}
}
答案 0 :(得分:0)
显示的代码中存在多个错误。
node* head= new node;
// ...
if (head->prev == NULL) {
您希望新构造的节点将prev
和next
指针初始化为NULL。
这是一个非常合理的期望。问题是你的代码中没有任何内容可以做到这一点:
struct node {
string data;
node *next;
node *prev;
};
如果没有明确的构造函数,new
就不会将next
和prev
初始化为任何内容。它们将是垃圾,显示的代码可能会尝试在某个时刻解除垃圾指针,导致崩溃。
您需要一个显式构造函数,将它们初始化为NULL(或使用当前C ++标准中引入的新语法,并为它们声明默认的初始化程序)。
这是第一个问题。
第二个问题是主for
循环被编码为迭代次数少于它需要的次数,出于某些无法解释的原因,并且有一个重复的代码块将最后一个值插入到链表中。我没有看到为什么需要这样做的任何理由。只需迭代所有字符,然后插入它们。
第三个问题是逻辑似乎在链表中插入了额外的head
和tail
节点,其数据将是一个空字符串。从它的外观来看,这将没有任何可见的效果,因为打印链表的循环将只打印一个空字符串。不过,这在技术上是错误的。
您需要调整逻辑以消除重复的虚假节点。首先将head
和tail
初始化为NULL
,而不是new
,大多数无用的节点:
node *head=NULL;
node *tail=NULL;
然后相应地调整for循环中的逻辑,以测试字符串中第一个字符的边缘条件,这将构造一个新节点,head
和tail
指向它,以及在head
之前插入每个后续字符的常规执行路径。