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

0

Я выяснил, как удалить все "A" узлы из текстового файла, "AHHHHHAAAAHHAAHAHHAHAHAAHAAHHA". Я смог написать функцию удаления узла, но он фокусируется только на удалении головы, но я хочу, чтобы эта функция могла читать файл и удалить все "A" и распечатать только все буквы H. Вот моя функция удаления узла

struct Node
{
    char data;
    Node* pPrev;
    Node* pNext;
};    

void deleteNode(Node * android)
{
   Node * pTemp = android->pNext;
   android->data = pTemp->data;
   android->pNext = pTemp->pNext;
   free(pTemp);
}

Вот другая функция узла удаления, которую я нашел здесь, которую я пытался изменить, я думаю, что это не сработает.

void deleteNode2(Node * android)
{
   Node * pNext;
   Node * pHead;
   Node * pTail;
   Node * pTemp = android->pNext;

   if(android->pNext == 'A')
   {
       pTemp = pNext;

       if(pHead = pTail)
       {
           pHead = pTail = NULL;
       }
       else
       {
           pHead = pHead->pNext;
       }
   } 
   free(pTemp);
}

в int main()

while( fscanf(pInFile, "%c", &c) != EOF)
    {
        appendNode( pTail, c);

        // display the list
        displayList( pTail->pNext);

    };

    cout << endl;
    cout << "'A' got removed from the List." << endl << endl;

    deleteNode2(pTail->pNext);
    displayList(pTail->pNext);
Теги:
linked-list
singly-linked-list

1 ответ

1
Лучший ответ

Строка if(android->pNext == 'A') даст вам ошибку компиляции: pNext - это Node*, и вы хотите сравнить данные. Замените это с помощью if (android->pNext.data == 'A').

Другая проблема заключается в том, что вы выполняете присваивание в условном выражении if, а не в сравнении: if(pHead = pTail) не будет сравнивать указатели, а вместо этого присваивает значение pHead pTail и оценивает значение true (как и в, введите оператор if), если pTail не был нулевым. Просто исправьте это, используя оператор ==.

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

Предполагая, что вы поместите этот фрагмент в свою основную функцию, вы должны попробовать что-то вроде этого:

Node* deleteNode(Node* android)
{
   if (android->next == android) { // only one element
       free(android);
       return NULL;
   } else {
       Node * pTemp = android->pNext;
       android->data = pTemp->data;
       android->pNext = pTemp->pNext;
       free(pTemp);
       return android;
   }
}

size_t listSize(const Node* pNode) {
    if (!pNode) return 0;
    const Node* pStart = pNode;
    size_t n = 0;
    do {
        pNode = pNode->pNext;
        n++;
    } while (pNode != pStart);
    return n;
}

Node * pTemp = pTail;
size_t len = listSize(pTail);
for (unsigned int i = 0 ; i < len ; i++) {
   if (pTemp.data == 'A') {
       pTemp = deleteNode(pTemp);
   } else {
       pTemp = pTemp->next;
   }
}

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

Чтобы закончить ответ: круговой связанный список может быть требованием, но вы можете сделать многое намного проще, если просто запретите программе добавлять символы "A". Опять же, это зависит от вашей конечной цели и того, чего вы требуете.

  • 0
    Спасибо! Но это только удаляет как 2 или 3 «А»? Есть намеки? @ E_net4
  • 0
    Что ж, я догадываюсь, что необходимо изменить условие цикла. Начальный узел может даже не существовать в конце обхода. Я исправлю это как можно скорее.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню