В этом коде я пытаюсь изменить список так, чтобы четные числа появлялись первыми в списке, а нечетные числа появлялись последними в списке, используя функцию evenOdd ().
Но ожидаемый результат не получается, выручите меня.

Ожидаемый выход:

Перед заказом:
1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> NULL
После заказа:
2 -> 4 -> 6 -> 1 -> 3 -> 5 -> 7 -> NULL

Фактический выход:

1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> NULL

#include<iostream>
using namespace std;

class Node
{
public:
    int data;
    Node* next;
};

void addEnd(Node **head, int val)
{
    Node *temp=*head;
    Node *newnode=new Node();
    newnode->data=val;
    newnode->next=NULL;
    if(*head == NULL) {*head = newnode; return;}
    while(temp->next!=NULL) {temp=temp->next;}
    temp->next=newnode;
}

void deleteKey(Node **head,int val)
{
    Node *temp=*head;
    Node* prev;
    if(temp!=NULL and temp->data == val)
    {
        *head = temp->next;
        delete temp;
        return;
    }
    while(temp->next!=NULL)
    {
        if(temp->data == val) {prev = temp; break;}
        prev=temp;
        temp=temp->next;
    }
    if(temp->data != val) {cout<<"NO SUCH VAlUES"; return;}
    prev->next=temp->next;
}

void evenOdd(Node **head)
{
    Node *temp = *head;
    while(temp != NULL)
    {
        if(temp->data%2 == 1)
        {addEnd(*(&head),temp->data); deleteKey(*(&head),temp->data);}
        temp = temp->next;
    }
}

void printList(Node *node)
{
    while(node!=NULL)
    {
        cout<<"  "<<node->data<<" --> ";
        node=node->next;
    }
    cout<<"NULL";
}

int main()
{
    Node *head = NULL;
    addEnd(&head,1);
    addEnd(&head,2);
    addEnd(&head,3);
    addEnd(&head,4);
    addEnd(&head,5);
    addEnd(&head,6);
    addEnd(&head,7);
    cout<<"Before Ordering :\n";
    printList(head);
    evenOdd(&head);
    cout<<"After Ordering :\n";
    printList(head);
    return 0;
}
0
Yadhu nandhan 13 Янв 2020 в 09:51

2 ответа

Лучший ответ

С этой комбинацией

if(temp->data%2 == 1)

А также

deleteKey(*(&head),temp->data);

Вы удаляете узел, который вы сейчас просматриваете. Включая фактический

delete temp;

Внутри deleteKey.

Но затем вы получаете доступ к памяти, которую вы только что удалили, здесь

temp = temp->next;

Внутри evenOdd.

После этого все ставки выключены.

Но наблюдаемая проблема возникает здесь внутри deleteKey:

prev->next=temp->next; 

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

{prev = temp; break;}

Но очевидно, что это не может получить указатель.
Вам нужно обновить это prev до конца, и тогда что-то вроде этого должно быть внутри вашего кода удаления

{prev->next = temp->next; break;} /* prev->next currently points to temp, but prev!= temp */
/* update the "next" pointing to current node so that it points to the next one */

Возможно, этот другой мой ответ окажется полезным для анализа подобных проблем Пуатье:
Трюки для анализа указателя и указателя структуры на указатель в C?

2
Yunnosch 13 Янв 2020 в 07:16

В функции evenOdd temp указывает на узел, вставленный сзади, тогда как он должен указывать на 2,3,4-й узел согласно итерации. поэтому, когда вы делаете temp = temp-> next, он переполняется.

0
user11555625user11555625 13 Янв 2020 в 07:11