在C++中以相反的顺序打印我的链接列表

Printing my linked list in reverse order in C++

本文关键字:打印 顺序 我的 链接 列表 C++      更新时间:2023-10-16

所以我对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;
}

现在我不确定我的代码崩溃的确切原因,任何帮助都将不胜感激!

谢谢!

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循环。您可以简单地在循环后立即停止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 *head)
{    
    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;
    }
}