2013-03-31 1 views
1
public void deleteItem(int target) 
{ 
    int index = 0; 
    CarNode item = head; 

    while(item != null) 
    { 

     CarNode next = (item.node).node; 
     CarNode previous = item; 

     if (index == target) 
     { 

      previous.setNode(next); 

     } 

    item = element.node 
    index++; 

    } 
} 

Да, я не знаю, хорошо ли я понял, но мне сказали, что вы можете использовать ссылку и не должны напрямую ссылаться на объект связанного списка, чтобы выполнять изменения в связанном списке ,Использование ссылок (временных переменных) для управления LinkedList?

Узел содержит объект «Автомобиль» и узел другого элемента LinkedList, справа, поэтому ссылка в основном представляет собой клон, который указывает на тот же объект, что и исходный, но почему оригинал игнорируется, а ссылка имеет приоритет над оригиналом, когда мы модифицируем узел ссылки? Извините, это не имело для меня никакого смысла, и я несколько часов царапаю голову над этим.

+2

Предлагаю вам ознакомиться с ссылкой и переформулировать ваш вопрос. Очень сложно понять, с чем вы столкнулись. _ «ссылка имеет преимущество перед оригиналом, когда мы модифицируем узел ссылки» _, похоже, не имеет большого смысла даже в контексте вашего кода. Можете ли вы отредактировать свой пост и перефразировать конкретный вопрос? –

+0

по ссылке i означает следующее и предыдущее, а не пункт. – user2089523

+0

Покажите нам определение 'CarNode' ... а также строку' CarNode next = (item.node) .node; 'похоже, что оба содержат ошибку (один из этих' node 'должен быть' next') _and_ также может означать, что следующий указатель находится в данных, хранящихся в списке, а не в списке, что будет проблемой дизайна. –

ответ

0

Код должен выглядеть следующим образом:

public void deleteItem(int target) 
{ 
    int index = 0; 
    CarNode item = head; 
    CarNode prev = null; 

    while(item != null) 
    { 
     if (index == target) { 
      if (prev == null) { 
       head = item.getNode(); 
       return; // We've removed the target. 
      } else { 
       prev.setNode(item.getNode()); 
       return; // We've removed the target. 
      } 
     } 
     prev = item; 
     item = item.getNode(); 
     index++; 
    } 
} 

Так давайте разберем это вниз:

int index = 0; 
CarNode item = head; 
CarNode prev = null; 

Нам нужны две переменные: одна для хранения элемента мы смотрим на, другой сохраните предыдущий элемент (который мы будем использовать для повторного подключения списка после удаления элемента). Для начала наш текущий - это голова, а наше предыдущее не существует. index сообщит нам, когда мы достигнем цели.

while(item != null) 

Мы хотим перебрать, пока мы не попали в конец списка, отмеченный null узлом.

if (index == target) { 
    if (prev == null) { 
     head = item.getNode(); 
     return; // We've removed the target. 
    } else { 
     prev.setNode(item.getNode()); 
     return; // We've removed the target. 
    } 
} 

Если мы нашли цель, мы удаляем ее. Если предыдущее значение равно NULL, цель была головой, поэтому мы перемещаем голову во второй элемент. В противном случае мы делаем ссылку предыдущего узла ссылкой на текущий узел, которая вырезает текущий узел из списка. Как только мы удалим цель, мы закончили, поэтому вернемся.

prev = item; 
item = item.getNode(); 
index++; 

Обновить предыдущие и текущие узлы. Оба перемещаются вперед на один узел. Индекс увеличивается.

Как о приведенном примере:

Возьмите список размера 3. Он выглядит следующим образом:

1

Мы теперь называем list.deleteItem(1); Это инстанцирует prev и next узла. next указывает на первый узел, а prev - null.

2

Наша цель 1, таким образом, мы переходим к следующему узлу. Теперь prev указывает на то, что next используется для указания, и next указывает на 2-й объект в списке (тот, который мы хотим удалить).

3

Снимаем его, установив ссылку на prev узла быть ссылка на next узла.

4

Когда мы возвращаемся из метода, сбор мусора Java делает свою работу, и мы остались с:

5

Тада! Узел удален из списка!

+0

ahh Мне трудно разобрать его, но что делает возврат точно? – user2089523

+0

prev.node = item.node; и previous.setNode (далее); эквивалентны, правильно? – user2089523

+0

'return' завершает текущий метод. А что касается 'previous.setNode (next)', это будет фактически правильный вызов, если 'node' не является общедоступным. Я отредактирую это. Оставайтесь на линии. –

1
public void deleteItem(int target) 
{ 
    int index = 0; 
    CarNode item = head; 

    CarNode next = null; 
    CarNode previous = null; 

    // stop when the linked-list ends 
    while(item != null) 
    { 
     // the tail has no next node 
     if (item.node != null) 
      next = item.node.node; 
     else 
      next = null; 

     // if targetIndex exist, remove it 
     //  "logically" from the linekd-list 
     if (index == target) 
     { 
      previous.setNode(next); 
      break; 
     } 

     // today is tomorrow's yesterday 
     previous = item; 
     item = item.node; 
     index++; 

    } 
} 
+0

Ах спасибо, так что было несколько ошибок, но серьезных ошибок логики. buw, почему вы нарушили? – user2089523

+0

проверить сейчас @ user2089523, я удалил цель, когда цель удалена, так как цель связана с индексом \ уникальный ключ, если она была связана со значением, мы можем иметь дело с несколькими вхождениями –

+0

@ user2089523 Использование Халедом 'break' это то же самое, что и мое использование «return» (для этого случая, по крайней мере): оно просто служит для выхода из метода, когда мы закончили. –