Правильная реализация методов двусвязного списка

Во-первых, извините за мой плохой английский.

Я пытаюсь реализовать Двусвязный список, но я не уверен, что некоторые его методы работают правильно. На самом деле, clear(), remove(const short DATA) - который удаляет все элементы, которые сравниваются равными DATA, unique() а также reverse() не работает правильно. Я не нашел ни одной книги, видео или статьи, которая была бы хороша. Я мог бы реализовать их по-своему, но я придерживаюсь формального пути (если есть), и решение для более опытного человека будет более эффективным, чем мое

void DLList::clear()
{
    Node *pCurr = mHead;
    while (pCurr != nullptr)
    {
        mHead = pCurr->mNext;
        delete pCurr;
        pCurr = mHead;
    }
}

void DLList::remove(const short DATA)
{
    Node *pCurr = mHead;
    while (pCurr != nullptr)
    {
        if (pCurr->mData == DATA)
        {
            if (pCurr == mHead)
            {
                mHead = pCurr->mNext;
                delete pCurr;
                pCurr = mHead;
            }
            else
            {
                Node *pPrev = pCurr->mPrev;
                pPrev->mNext = pCurr->mNext;
                delete pCurr;
                pCurr = pPrev->mNext;
            }
        }
        else
            pCurr = pCurr->mNext;
    }
}

void DLList::unique()
{
    Node *pCurr = mHead;
    while (pCurr != nullptr)
    {
        Node *pNextDistinct = pCurr->mNext;
        while (pNextDistinct != nullptr && pNextDistinct->mData == pCurr->mData)
        {
            pNextDistinct = pNextDistinct->mNext;
            delete pCurr->mNext;
            pCurr->mNext = pNextDistinct;
            pNextDistinct->mPrev = pCurr;
        }
        pCurr = pNextDistinct;
    }
}

void DLList::reverse()
{
    Node *pPrev = nullptr;
    Node *pCurr = mHead;
    while (pCurr != nullptr)
    {
        pCurr->mPrev = pCurr->mNext;
        pCurr->mNext = pPrev;
        pPrev = pCurr;
        pCurr = pCurr->mPrev;
    }
    mHead = pPrev;
}

1 ответ

Я исправил ваши методы, чтобы они хорошо работали. Пожалуйста, сравните ваши ошибки, а также прочитайте мой комментарий в коде. При кодировании структуры данных всегда используйте бумагу и ручку и сначала запишите структуру дерева или списка, которая поможет вам сначала спроектировать алгоритм, а затем код. Пожалуйста, дайте мне знать, если вам нужна дополнительная помощь.

//In the below method you are deleting unique nodes
void DLList::unique()
{
    Node *pCurr = mHead;
    Node *temp = NULL;
    int data = 0;
    while (pCurr != NULL)
    {
       data = pCurr->mData;
       temp = pCurr;
       while(temp != NULL)
       {
           temp = temp->mNext;
           if(temp->mData == data)
           {
              //delete the duplicate node
              temp->mPrev->mNext = temp->mNext;
              if(temp->mNext != NULL)
                  temp->mNext->mPrev = temp->mPrev;
              delete(temp);
           }
       }
      pCurr = pCurr->mNext; 
    }
}


void DLList::reverse()
{
    Node *temp = NULL, *q = NULL;
    while (temp->mNext != NULL)
      temp = temp->mNext;
    //now temp is pointing to the last node of the list
    //Assume that mHead->mPrev == null, because I dont know whether it is null or address of Head itself
    //if Head node mPrev is holding the address of head then you must store the address of head in a pointer
    //to check whether you reach head node or not
    //as I assume it is null so I don't need a temporary pointer here
    mHead = temp; //now head is pointing to the last node
    q = temp->mPrev;//pointer q is pointing to the previous node of the last node
    temp->mPrev = NULL;//as last node is now first node make it's previous pointer as NULL
    while(q!=NULL)// now traverse toward the old head node who's prev pointer is set as NULL
    {
       temp->mNext = q;
       q->mPrev = temp;
       temp = q; //move temp to the old previous node
       q = q->mPrev;// Move q to the previous node
    }
    //Now temp is pointing to the old head node
    temp->mNext = NULL;//Your list is reversed finally
}

Реверс может быть выполнен и от головы до последнего узла. Теперь вы просто записываете список на бумаге и думаете, как вы можете это сделать и сколько указателей вам нужно для этого. Удачи:-)

Другие вопросы по тегам