Зачем сохранять «предыдущий» при удалении дубликатов в связанном списке?

#list #linked-list #duplicates #hashtable

#Список #связанный список #дубликаты #хэш-таблица

Вопрос:

мне было интересно, может ли кто-нибудь объяснить, какова цель использования переменной ‘LinkedListNode previous’. я понимаю общую идею попытки удалить дубликат. вы просматриваете связанный список и, если значения нет в хэш-таблице, вставляете его. но если это так, что это делает? я не совсем уверен.

большое спасибо за помощь! я был бы очень признателен, если бы кто-нибудь мог объяснить это ясным и легким для понимания способом. Спасибо!

 public static void deleteDups(LinkedListNode n) {
    Hashtable table = new Hashtable();
    LinkedListNode previous = null;
    while (n != null) {
        if (table.containsKey(n.data)) previous.next = n.next;
        else {
            table.put(n.data, true);
            previous = n;
        }
        n = n.next;
    }
}
  

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

1. Без «предыдущего», как цепочка минусов связанного списка оставалась бы подключенной?

Ответ №1:

Без «предыдущего», как цепочка минусов связанного списка оставалась бы подключенной?

Представьте: Prev->Current->Next во что нужно превратить, Prev->Next если Current элемент должен быть удален из списка. Если Prev он не был сохранен временно, то его нельзя было изменить для обновления ссылки. (Если бы список был двусвязным, то Prev он не был бы нужен, потому что из него можно было бы восстановить Current->previous ).

Удачного кодирования.


В ответ на вопрос в комментарии:

Если ничего не сделано, то дублирующий элемент не отключается от списка. n = n.next изменяет значение n (но не изменяет данные элемента / узла, хранящиеся в n или в другом месте, поэтому Prev.next никогда не изменяются из Current ).

Что нужно сделать, так это то, что next of Prev , элемент / узел перед удаленным элементом, должен быть обновлен, чтобы ссылаться на элемент ( Next ) после удаленного элемента.

 previous.next = n.next; // and this does it
  

(Это также можно было бы написать в функциональном стиле без изменений, где исходный список не изменяется, а создается новый список — в этом случае не было бы необходимости Prev ).

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

1. Разве удаление не просто пропускает дублирующий элемент? Если да, то внутри инструкции ‘if’ не могли бы вы просто ничего не делать? И затем в конце цикла while он увеличит n на n = n.далее, итак, теперь посмотрим на следующий элемент?

Ответ №2:

 public static void deleteDup( LinkedList* h){

    if( !h || !h->next )
        return;
    Hashtable ht = new Hashtable();
    LinkedListNode* previous = h;
    LinkedListNode* curr = h->next;
    while( curr ){
        if( ht.containsKey() ){
            previous->next = curr->next;
            free(curr);
            curr = previous->next;

        }
        else{
            ht.put(curr->data, true );
             previous = curr;
             curr = curr->next;
        }
    }
}