2014-10-28 8 views
1

Я использую указатели в первый раз. У меня есть программа, которая вставляет числа в связанный список, печатает список и удаляет определенные числа из списка. Он работает, за исключением случаев, когда я пытаюсь удалить номер, который был вставлен последним.Как удалить последний элемент, добавленный в связанный список в C++

node.h

#ifndef Node_h 
#define Node_h 

#include <iostream> 
using namespace std; 

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

public: 
Node(); 
}; 

#endif 

node.cpp

#include "Node.h" 

Node::Node() 
{ 
} 

LinkedList.h

#ifndef LinkedList_h 
#define LinkedList_h 

#include "Node.h" 

class LinkedList 
{ 
    private: 
    Node *pL; 

public: 
    LinkedList(); 
    void insert(int nr1); 
    void deleteNr(int nr1); 
    void printL(); 
}; 

#endif 

LinkedList.cpp // Эта программа создает "связанный список" от числа

#include "LinkedList.h" 

LinkedList::LinkedList() 
{ 
    pL = NULL; 
} 

void LinkedList::insert(int nr1) 
{ 
    Node *p = new Node; 
    p->data = nr1; 
    p->next = pL; 
    pL = p; 
} 

void LinkedList::deleteNr(int nr1) 
{ 
    Node *p = pL; 
    Node *p2 = pL; 
    while (p != NULL & p->data != nr1) 
    { 
     p2 = p; 
     p = p->next; 
    } 

    if (p != NULL) 
    { 
     p2->next = p->next; 
     delete p; 
    } 
} 

void LinkedList::printL() 
{ 
    Node *p = pL; 

    while (p != NULL) 
    { 
     cout << p->data << "-> "; 
     p = p->next; 
    } 
} 

main.cpp

#include "LinkedList.h" 

int menu(); 

//////// main ///////// 
int main() 
{ 
    int choice1, nr1; 
    LinkedList lk1; 

    choice1 = menu(); 

    while (choice1 <= 3) 
    { 
     if (choice1 == 1) 
     { 
      cout << "Enter number." << endl; 
      cin >> nr1; 
      lk1.insert(nr1); 
     } 

     else if (choice1 == 2) 
     { 
      cout << "Enter number." << endl; 
      cin >> nr1; 
      lk1.deleteNr(nr1); 
     } 

     else if (choice1 == 3) 
     { 
      lk1.printL(); 
      cout << endl << endl; 
     } 

     else if (choice1 == 4) 
     { 
      cout << "Exit the program." << endl; 
      system("pause"); 
      exit(1); 
     } 

     choice1 = menu(); 
    } // end while loop 
} 

int menu() 
{ 
    int choice1; 

    cout << "1. Insert a number into the linked-list." << endl; 
    cout << "2. Delete a number from the linked-list." << endl; 
    cout << "3. Print the linked-list." << endl; 
    cout << "4. Exit the program." << endl; 
    cout << "Enter choice." << endl; 
    cin >> choice1; 

    return choice1; 
} 
+2

Домашнее задание? Что происходит, когда вы пытаетесь удалить последний вставленный элемент? – Alex

+0

Да, это домашнее задание. Когда я пытаюсь удалить последний вставленный элемент, он сработает. – user3254558

+0

Просто обратите внимание, что в вашей функции удаления у вас есть '&' где это должно быть '&&'. Они делают разные вещи. – Daniel

ответ

0

Вам нужно добавить код, чтобы иметь дело с случаем, когда данный ввод соответствует первому элементу в списке.

void LinkedList::deleteNr(int nr1) 
{ 
    Node *p = pL; 

    if (p != NULL && p->data == nr1) 
    { 
     pL = p->next; 
     delete p; 
     return; 
    } 

    Node *p2 = pL; 
    while (p != NULL && p->data != nr1) 
    { 
     p2 = p; 
     p = p->next; 
    } 

    if (p != NULL) 
    { 
     p2->next = p->next; 
     delete p; 
    } 
} 
+0

Это прекрасно работает. Спасибо! Не могли бы вы вкратце объяснить, что я сделал не так, и что вы исправили? Я довольно смущен. – user3254558

+0

Проверьте свои & операторы. Этот код неверен. – Daniel

+0

@ Даниэль, он исправлен. –

1

Ваша проблема в том, что, как правило, р2 один узел за р в списке, но если первый узел должен быть удален, то первое время цикла в функции удаления была 0 итераций и р2 и р одинаковы. Голова удалена, но pL не обновляется. Это просто указывает на нераспределенную память. Это может привести к тому, что узел не будет удален, или это может привести к сбою сегментации и сбою. В любом случае, это неправильное поведение. Вам необходимо убедиться в том, что удаляемый узел - это первый узел и обновление pL.

Try что-то вроде этого

void LinkedList::deleteNr(int nr1) 
{ 
    Node *p = pL; 
    Node *p2 = pL; 
    if(p != NULL && nr1 == p->data) 
    { 
     pL = p->next; 
     delete p; 
     return; 
    } 

    while (p != NULL && p->data != nr1) 
    { 
     p2 = p; 
     p = p->next; 
    } 

    if (p != NULL) 
    { 
     p2->next = p->next; 
     delete p; 
    } 
} 

Если вы хотите, чтобы иметь возможность удалить все экземпляры nr1 в связанном списке, вам нужно добавить еще один цикл:

void LinkedList::deleteNr(int nr1) 
{ 
    Node *p = pL; 
    while(p != NULL && nr1 == p->data) 
    { 
     pL = p->next; 
     delete p; 
     p = pL; 
    } 
    Node *p2 = pL; 

    while (p != NULL) 
    { 
     p2 = p; 
     p = p->next; 
     if(nr1 == p->data) 
     { 
      p2->next = p->next; 
      delete p; 
     } 
    } 
} 
+0

Это работает и не работает. Да, вы можете удалить последний введенный номер, потому что он будет удалять номера в списке в обратном порядке, в котором они были введены, но вы не можете удалить определенные числа. – user3254558

+0

@ user3254558 Я не понимаю, что вы имеете в виду? – Daniel

+0

@ user3254558 Это удалит все экземпляры номера nr1 в связанном списке. – Daniel

-1
void LinkedList::deleteLast() 
{ 

Node *p = pL; 

if(p == NULL) 
    return; 
else if(p->next == NULL) { 
    p = NULL; 
} 
else { 
    while (p->next->next != NULL) 
    { 
    p = p->next; 
    } 

    p->next = NULL; 
} 
} 
+1

Я не думаю, что это действительно ответ, который ищет OP. Название вопроса мало вводит в заблуждение. Кроме того, на каком языке этот код? Это похоже на комбинацию Java и C++. – Daniel

+0

Это язык C++. Является ли это новой функцией специально для удаления последнего элемента и для вызова в основной функции? – user3254558

+0

@ user3254558 Он использует нижний регистр null, который является Java. Также не удаляет узлы, которые также похожи на Java. – Daniel