Печать связанного списка в обратном порядке на C++
поэтому я довольно новичок в C++ , и сегодня я решил сесть и понять, как работают связанные списки. До сих пор мне было очень весело, но я столкнулся с проблемой при попытке распечатать связанный список в обратном порядке (а не в обратном порядке связанного списка!)
кроме того, я хотел сделать это без двойного связанного списка:
#include <iostream>
#include <string>
using namespace std;
class LinkedList
{
public:
LinkedList()
{
head = NULL;
}
void addItem(string x)
{
if(head == NULL)
{
head = new node();
head->next = NULL;
head->data = x;
} else {
node* temp = head;
while(temp->next != NULL)
temp = temp->next;
node* newNode = new node();
newNode->data = x;
newNode->next = NULL;
temp->next = newNode;
}
}
void printList()
{
node *temp = head;
while(temp->next != NULL)
{
cout << temp->data << endl;
temp = temp->next;
}
cout << temp->data << endl;
}
void addToHead(string x)
{
node *temp = head;
head = new node;
head->next = temp;
head->data = x;
}
int countItems()
{
int count = 1;
for(node* temp = head; temp->next != NULL; temp = temp->next)
++count;
return count;
}
void printReverse()
{
node* temp2;
node* temp = head;
while(temp->next != NULL)
temp = temp->next;
//Print last node before we enter loop
cout << temp->data << endl;
for(double count = countItems() / 2; count != 0; --count)
{
//Set temp2 before temp
temp2 = head;
while(temp2->next != temp)
temp2 = temp2->next;
cout << temp2->data << endl;
//Set temp before temp2
temp = head;
while(temp->next != temp2)
temp = temp->next;
cout << temp->data << endl;
}
cout << "EXIT LOOP" << endl;
}
private:
struct node
{
string data;
node *next;
}
*head;
};
int main()
{
LinkedList names;
names.addItem("This");
names.addItem("is");
names.addItem("a");
names.addItem("test");
names.addItem("sentence");
names.addItem("for");
names.addItem("the");
names.addItem("linked");
names.addItem("list");
names.printList();
cout << endl;
names.addToHead("insert");
names.printList();
cout << endl;
cout << names.countItems() << endl;
cout << "Print reverse: " << endl;
names.printReverse();
cout << endl;
return 0;
}
теперь я не уверен, почему мой код падает, любая помощь приветствуется!
спасибо!
6 ответов
внутри printList
, вы также должны проверить для head == NULL
, в противном случае вы используете члены указателя, указывающего на NULL
. Должно сработать следующее.
void printList()
{
node *temp = head;
while(temp != NULL) // don't access ->next
{
cout << temp->data << endl;
temp = temp->next;
}
}
на printReverse()
Я действительно не могу понять, почему вы берете половину количества элементов для печати и печати двух элементов в каждой итерации. Однако вам действительно не нужен for-loop здесь. Вы можете просто остановиться, как только temp == head
после вашего цикла, с тех пор вы просто напечатали голову. И только один элемент печати, тот, чей следующий указатель указывает на ранее напечатанный элемент.
другая, рекурсивная, попытка решить проблему выглядит так:
void printReverse()
{
printReverseRecursive(head);
}
void printReverseRecursive(node *n)
{
if(n) {
printReverseRecursive(n->next);
cout << n->data << endl;
}
}
void printReverse()
{
printReverse(head) //kickstart the overload function below
}
void printReverse(node *n)
{
if(n == 0) return;
printReverse(n->next); //print the next
cout << n->data << endl; //before printing me
}
вы должны рассмотреть возможность перезаписи цикла, чтобы начать с последнего элемента (как вы это сделали) и остановить условие цикла, когда вы достигнете head
. Двойной код внутри for
петля, вместе с нечетным count/2
логика, конечно, смущает вас (и нас).
temp = [last element]
while not at head
print temp
temp = previous element
print head
обратите внимание, что у вас уже есть код temp = previous element
детали:
temp2 = head;
while(temp2->next != temp)
temp2 = temp2->next;
поскольку я предполагаю, что это назначение какого-то типа, Я намеренно не даю вам код C++ для этот. Даже если это не задание, работа с ним с учетом этого должна быть учебным опытом, который вам нужен. Однако, если вы даете ему шанс и все еще имеете проблему, не стесняйтесь обновлять свой вопрос (или публиковать новый).
for(double count = countItems() / 2; count != 0; --count)
{
//Set temp2 before temp
temp2 = head;
while(temp2->next != temp)
temp2 = temp2->next;
cout << temp2->data<< " " << endl;
//Set temp before temp2
temp = head;
while(temp->next != temp2)
temp = temp->next;
cout << temp->data << " "<< endl;
}
cout << "EXIT LOOP" << endl;
ваша программа аварийно завершает работу из-за второго контура. Подсказка: пройдите через него только с двумя элементами, добавленными в список, например "Hello" - > " You " - > NULL. И посмотрите ближе к вашему предикату цикла (temp- > next != temp2).
void ReversePrint (узел * головка) {
Node *curNode=head;
if(curNode!=NULL){
if(curNode->next!=NULL){
ReversePrint(curNode->next);
}
cout<<curNode->data<<endl;
}
}
оператор печати должен быть таким образом:
void print() {
node *temp;
temp= head;
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->next;
}
}