Удаление всего узла из односвязного списка

#c #linked-list

#c #связанный список

Вопрос:

Я пытался, но не могу заставить это работать. Мне нужно удалить номер элемента из связанного списка. Вот что я сделал до сих пор:

 class MatrixLL
{
private:
    struct MatrixLLElem
    {
        Matrix elem;
        MatrixLLElem* next;
        MatrixLLElem(const Matrixamp; m1): elem(m1), next(NULL)
        { }
    };
    MatrixLLElem* start;
public:
    MatrixLL();
    Matrixamp; elem(const int index);
    int getlength();
    void append(const Matrixamp; m1);
    void deleteelem(const int index);
    ~MatrixLL();
};
  

Мой другой код не вызывает беспокойства, поскольку он работает отлично, поэтому вот код для функции deleteelem();:

 void MatrixLL::deleteelem(const int index)
{
    if(index < 1)
        throw "Invalid index specified.";

    if(start == NULL)
        throw "No element at specified location.";

    MatrixLLElem* currP = start;
    MatrixLLElem** prevP = NULL;

    for(int i = 1; i < index; i  )
    {
        prevP = amp;currP;
        if((*currP).next != NULL)
            currP = (*currP).next;
        else
            throw "No element at specified location.";
    }
    if(prevP == NULL)
    {
        start = NULL;
    }
    else
    {
        (*prevP) = (*currP).next;
    }
    delete currP;
}
  

РЕДАКТИРОВАТЬ: это уменьшает длину с 2 до 0, если я проверю… И функция длины, похоже, работает нормально, если я добавляю, а затем проверяю и т.д. Предполагается, что индекс начинается с 1.

Ответ №1:

Проблема заключается в том, что вы хотите удалить первый элемент (index = 1).

вместо

 start = NULL; // wrong
  

правильный:

 start = (*currP).next; // the second element now becomes the first element
  

Ответ №2:

Я все понял правильно. Если это кому-то поможет, вот код:

 void MatrixLL::deleteelem(const int index)
    {
    if(index < 1)
        throw "Invalid index specified.";

    if(start == NULL)
        throw "No element at specified location.";

    MatrixLLElem* currP = start;
    MatrixLLElem* prevP = NULL;

    for(int i = 1; i < index; i  )
    {
        prevP = currP;
        if((*currP).next != NULL)
            currP = (*currP).next;
        else
            throw "No element at specified location.";
    }

    if(prevP != NULL)
    {
        (*prevP).next = (*currP).next;
    }
    else
    {
        start = (*start).next;
    }

    delete currP;
}
  

Просто для справки, начальный индекс равен 1, а не 0.

Ответ №3:

 (*prevP) = (*currP).next;
  

должно быть

 (*prevP).next = (*currP).next;
  

Комментарии:

1. prevpявляется двойным указателем. Так и должно быть. Если я изменю его на один указатель и соответствующим образом отредактирую код, он удалит оба указателя, если я укажу ему местоположение 1.

Ответ №4:

Похоже, что условие и часть с изменяющимися указателями неверны. Должно быть так:

 MatrixLLElem* prevP = NULL; // Why ** ?

for(int i = 1; i <= index;   i) // Here
{
    prevP = currP;
    if((*currP).next != NULL)
        currP = (*currP).next;
    else
        throw "No element at specified location.";
}
if(currP == start) // This would be better
{
    start = NULL;
}
else
{
    (*prevP).next = (*currP).next; // And here
}
delete currP;
  

Комментарии:

1. Ваш код, вероятно, правильный, если индекс начинается с 0. Кроме того, prevP — это двойной указатель.

2. Зачем вам двойной указатель? Что ж, вы можете сделать это двумя способами… Но я думаю, что двойной указатель более подвержен ошибкам.