在 C++ 中以相反的顺序打印我的链表
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14177337/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Printing my linked list in reverse order in C++
提问by Marcan
So I'm fairly new to C++ and today I decided to sit down and understand how linked lists work. I'm having a lot of fun doing it so far, but I've encountered a problem when trying to print my linked list in reverse order (not reverse the order of the linked list!)
所以我对 C++ 相当陌生,今天我决定坐下来了解链表的工作原理。到目前为止,我玩得很开心,但是在尝试以相反的顺序打印我的链表时遇到了问题(而不是颠倒链表的顺序!)
Also, I wanted to do this without having a double linked list:
另外,我想在没有双链表的情况下做到这一点:
#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;
}
Now I'm not sure exactly why my code crashes, any help is appreciated!
现在我不确定我的代码崩溃的确切原因,任何帮助表示赞赏!
Thanks!
谢谢!
采纳答案by leemes
Within printList
, you have to also check for head == NULL
, otherwise you are acessing members of a pointer pointing to NULL
. The following should work.
在其中printList
,您还必须检查head == NULL
,否则您正在访问指向 的指针的成员NULL
。以下应该工作。
void printList()
{
node *temp = head;
while(temp != NULL) // don't access ->next
{
cout << temp->data << endl;
temp = temp->next;
}
}
In printReverse()
I really can't understand why you take half of the counts of the elements to print and print two elements in every iteration. However, you really don't need a for-loop here. You can simply stop as soon as temp == head
after your loop, since then you just printed the head. And only print one element, the one whose next pointer points to the previously printed element.
在printReverse()
我真的不明白为什么你把元素计数的一半打印出来并在每次迭代中打印两个元素。但是,您在这里真的不需要 for 循环。您可以temp == head
在循环结束后立即停止,因为您只是打印了头部。并且只打印一个元素,该元素的 next 指针指向先前打印的元素。
Another, recursive, attempt to solve the problem looks like this:
另一种递归的解决问题的尝试如下所示:
void printReverse()
{
printReverseRecursive(head);
}
void printReverseRecursive(node *n)
{
if(n) {
printReverseRecursive(n->next);
cout << n->data << endl;
}
}
回答by JaredC
You should consider re-writing your loop to start at the last element (as you have done) and have your loop condition stop when you reach the head
. Having double the code inside your for
loop, along with the odd count/2
logic is certainly confusing you (and us).
您应该考虑重新编写循环以从最后一个元素开始(正如您所做的那样),并在到达head
. 将for
循环中的代码加倍,加上奇怪的count/2
逻辑肯定会让您(和我们)感到困惑。
temp = [last element]
while not at head
print temp
temp = previous element
print head
Note that you already have the code for the temp = previous element
part:
请注意,您已经拥有该temp = previous element
部件的代码:
temp2 = head;
while(temp2->next != temp)
temp2 = temp2->next;
Since I assume this is an assignment of some type, I'm intentionally not giving you the c++ code for this. Even if it isn't assignment, working through it with this in mind should be the learning experience you're after. However, if you give it a shot and still have a problem, feel free to update your question (or post a new one).
由于我认为这是某种类型的分配,因此我故意不为此提供 C++ 代码。即使这不是作业,记住这一点也应该是你所追求的学习体验。但是,如果您试一试但仍有问题,请随时更新您的问题(或发布新问题)。
回答by JaredC
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
}
回答by kaan
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;
Your program crashes because of the second loop. Hint: Go through it with only two elements added to the list, e.g."Hello" -> "You" -> NULL. And look closer to your loop-predicate (temp->next != temp2).
由于第二个循环,您的程序崩溃了。提示:通过只添加两个元素到列表中,例如"Hello" -> "You" -> NULL。并仔细观察您的循环谓词(temp->next != temp2)。
回答by Jay
void ReversePrint(Node *head)
{
Node *curNode=head;
if(curNode!=NULL){
if(curNode->next!=NULL){
ReversePrint(curNode->next);
}
cout << curNode->data << endl;
}
}
回答by Butterfly
print statement should be in this manner:
打印语句应该是这样的:
void print() {
node *temp;
temp= head;
while (temp != NULL) {
cout << temp->data << " ";
temp = temp->next;
}
}