10

ですから、私は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;
}

コードがクラッシュする理由が正確にはわかりません。助けていただければ幸いです。

ありがとう!

4

6 に答える 6

4

printListでは、もチェックする必要head == NULLがあります。そうしないと、を指すポインタのメンバーにアクセスすることになりNULLます。以下が機能するはずです。

    void printList()
    {
        node *temp = head;
        while(temp != NULL) // don't access ->next
        {
            cout << temp->data << endl;
            temp = temp->next;
        }
    }

ではprintReverse()、要素のカウントの半分を使用して、すべての反復で2つの要素を印刷および印刷する理由を本当に理解できません。ただし、ここではforループは実際には必要ありません。ループが終わったらすぐに停止できtemp == headます。それ以降は、ヘッドを印刷しただけです。そして、次のポインタが前に印刷された要素を指している要素を1つだけ印刷します。

問題を解決するための別の再帰的な試みは、次のようになります。

    void printReverse()
    {
        printReverseRecursive(head);
    }
    void printReverseRecursive(node *n)
    {
        if(n) {
            printReverseRecursive(n->next);
            cout << n->data << endl;
        }
    }
于 2013-01-05T23:08:12.607 に答える
2

(行ったように)最後の要素から開始するようにループを書き直し、に達したときにループ条件を停止することを検討する必要がありますheadforループ内にコードを2倍にすることと、奇妙な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++コードを提供していません。課題でなくても、これを念頭に置いて取り組むことが、あなたが求めている学習体験になるはずです。ただし、試してみても問題が解決しない場合は、質問を更新してください(または新しい質問を投稿してください)。

于 2013-01-05T23:17:06.347 に答える
2
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
}
于 2013-01-05T23:32:30.813 に答える
1
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;

2番目のループが原因でプログラムがクラッシュします。ヒント:リストに2つの要素のみを追加して、「こんにちは」->「あなた」->NULLなどの要素を追加してください。そして、ループ述語(temp-> next!= temp2)をよく見てください。

于 2013-01-05T23:49:30.000 に答える
1
void ReversePrint(Node *head)
{    
    Node *curNode=head;

    if(curNode!=NULL){
        if(curNode->next!=NULL){
            ReversePrint(curNode->next);
        }
        cout << curNode->data << endl;
    }
}
于 2017-09-17T08:38:30.620 に答える
0

printステートメントは次のようにする必要があります。

void print() {
    node *temp;
    temp= head;
    while (temp != NULL) {
        cout << temp->data << " ";
        temp = temp->next;
    }
}
于 2017-08-02T05:16:54.213 に答える