Почему этот оператор if запускается в этом коде C ++? - PullRequest
0 голосов
/ 20 июня 2020

Этот код должен перевернуть связанный список. Следующий код возвращает пустой связанный список, даже если он предоставлен с непустым списком.

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* curr, *prev, *next;
        if (head == NULL)
        {
            return head;   
        }   
        curr = head;
        prev = NULL;
        while (curr != NULL)
        {
            next = curr -> next;
            curr -> next = prev;
            prev = curr;
            curr = next;
        }
        head = prev;
        return head;
    }
};

Хотя этот код странным образом работает там, где я добавил оператор cout, просто чтобы проверить, был ли запущен else.

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* curr, *prev, *next;
        if (head == NULL)
        {
            cout << "Triggered";
            return head;   
        }   
        curr = head;
        prev = NULL;
        while (curr != NULL)
        {
            next = curr -> next;
            curr -> next = prev;
            prev = curr;
            curr = next;
        }
        head = prev;
        return head;
    }
};

Кто-нибудь может объяснить, почему это происходит?

Ответы [ 2 ]

2 голосов
/ 20 июня 2020

Довольно просто, вам нужно инициализировать pointers, иначе это приведет к неожиданному поведению, которое включает в себя не показывать его вообще или просто показывать, если инициализированный cout запускается, но он не должен ничего делать и это зависит от реализации вашего компилятора.

//cpp17
    listNode* curr{}, *prev{}, *next{};

//before
    listNode* curr = nullptr, *prev = nullptr, *next = nullptr;

Это все еще не в обратном порядке, как вы планировали.

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        listNode* curr{}, *prev{}, *next{};
        //ListNode* curr, *prev, *next;
        if (head == NULL)
        {
            return head;   
        }   
        curr = head;
        prev = NULL;
        while (next != NULL)
        {
            next = curr -> next;
            curr -> next = prev;
            prev = curr;
            curr = next;
        }
        head = prev;
        return head;
    }
};

ура :)

1 голос
/ 24 июня 2020

Как упоминалось ранее, я нашел время написать решение для другого подхода к решению вашей проблемы, чтобы перевернуть связанный список через класс. Для лучшего понимания новичков я пропустил правило три / пять и инициализировал список в основной функции, а не через конструктор в классе:

#include <iostream>

class listElement
{
    std::string data;
    listElement* next;
    listElement* last;


public:
    void setData(std::string);
    void append(std::string);
    void displayElements();
    void reverseDisplayElements(listElement*);
    void freeMemory();

    listElement* reverseList(listElement*);
};

void listElement::setData(std::string newData)
{
    last = this;
    data = newData;
    next = nullptr;
}

void listElement::append(std::string newData)
{
// Double linked list
//    last->next = new listElement();
//    last->next->data = newData;
//    last->next->next = nullptr;
//    last = last->next;

// Singly linked list
    //has next the value nullptr?
    //If yes, next pointer
    if (next == nullptr)
    {
        next = new listElement();
        next->data = newData;
        next->next = nullptr;
    }
    //else the method again
    else
        next->append(newData);
}

listElement* listElement::reverseList(listElement* head)
{
    //return if no element in list
    if(head == nullptr)
        return nullptr;

    //initialize temp
    listElement* temp{};

    while(head != nullptr){
        listElement* next = head->next;
        head->next = temp;
        temp = head;
        head = next;
    }
    return temp;
}

void listElement::displayElements()
{
    //cout the first entry
    std::cout << data << std::endl;
    //if the end is not reached, call method next again
    if (next != nullptr)
        next->displayElements();
}

void listElement::reverseDisplayElements(listElement*head)
{
    //recursiv from the last to the list beginning - stop
    listElement *temp = head;

    if(temp != nullptr)
    {
        if(temp->next != nullptr)
        {
            reverseDisplayElements(temp->next);
        }
      std::cout << temp->data << std::endl;
    }
}
void listElement::freeMemory()
{
    //If the end is not reached, call the method again
    if (next != nullptr)
    {
        next->freeMemory();
        delete(next);
    }
}

int main ()
{
    //Pointer to the Beginning of the list
    listElement* linkedList;

    //Creating the first element
    linkedList = new listElement();
    //Write data in the first element
    linkedList->setData("Element 1");

    //add more elements
    linkedList->append("Element 2");
    linkedList->append("Element 3");
    linkedList->append("Element 4");

    //display list
    linkedList->displayElements();

    //space divider
    std::cout << "\nPrint in reverse order:" << std::endl;

    //display list in reverse order
    //pass list beginning as stop point
    linkedList->reverseDisplayElements(linkedList);
    std::cout << std::endl;

    linkedList->displayElements();
    std::cout << "\nReverse elements:" << std::endl;

    linkedList = linkedList->reverseList(linkedList);
    linkedList->displayElements();

    std::cout << std::endl;

    //destruct the list and free memory
    linkedList->freeMemory();
    delete(linkedList);

    return 0;
}

Btw. есть много различных решений для этой задачи.

...