2014-11-16 9 views
1

У меня есть класс Java, который состоит из списка узлов, WordNode, который имеет атрибуты класса Word и объект WordNode под названием next используется в качестве ссылки на следующий узел следующим образом:Java LinkedList удаление последнего узла

class WordNode 
{ 
    Word word; 
    WordNode next; 

    WordNode(Word w) 
    { 
     word = w; 
     next = null; 
    } 

    Word getWord() 
    { 
     return word; 
    } 
} 

а класс Word имеет строку под названием name:

class Word 
{ 
    String name; 

    Word(String n) 
    { 
      this.name = n; 
    } 

    public String getName() 
    { 
      return name;  
    } 

    public void setName(String n) 
    { 
     name = n; 
    } 
} 

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

boolean remove(Word w) 
{ 
    WordNode wm = new WordNode(w); 

    if (list == null) return false; //can't delete on an empty list 
    else 
    { 
     WordNode aux = list; 

     while(aux != null) 
     { 
      if (wm.word.getName().compareTo(aux.word.getName()) == 0) //if the word to delete is found 
      { 
       if (aux.next == null) //to erase the last element 
       { 
        aux = null;  
       } 
       else 
       { 
        aux.word.setName(aux.next.word.getName()); //set current node's name to equal next node's 

        WordNode temp = aux.next.next; 
        aux.next = null; //to erase current node 
        aux.next = temp; //re-refer 
       }       
       return true; 
      } 
      else aux = aux.next; 
     } 

     return false; //reachable if word is not found 
    } 
} 

Где list должен быть LinkedList, который содержит все узлы. aux - это вспомогательный список, который будет циклически проходить через list, чтобы избежать не связывания. Итак, если я захочу удалить WordNode, я сравню имена. Это на самом деле удаления хорошо, когда узел находится в любом месте, за исключением последний узел:

if (aux.next == null) //to erase the last element 
{ 
    aux = null;  
} 

Я надеюсь сделать этот узел нуль, чтобы отметить новый конец списка, но это не делает стирайтесь. Что я могу изменить, чтобы стереть последний элемент? Спасибо за любую помощь/предложения заблаговременно

+1

aux = null просто устанавливает вашу ссылку на объект, aux, на null. Лучший способ - просто aux.prev.next = null – Ben

+0

Однако у меня нет поля 'prev'. Но разве это не так, как 'aux = null'? – gfcf14

+0

'if (aux.next == null)' просто скажу вам, что ваш aux - последний узел в списке. Установка ссылки на последний элемент на null не влияет на предыдущий узел, потому что его следующий узел до ссылки на элемент, который, по вашему мнению, был удален. Вот почему вам нужно отслеживать свой предыдущий узел. – Kalenda

ответ

2

Вы должны очистить «следующий» указатель на WordNode в. Поскольку у вас нет «предыдущего» указателя, вам нужно следить за предыдущим WordNode вручную.

boolean remove(Word w) 
{ 
    WordNode wm = new WordNode(w); 

    if (list == null) return false; //can't delete on an empty list 
    else 
    { 
     WordNode aux = list; 
     WordNode prev = aux; 

     while(aux != null) 
     { 
      if (wm.word.getName().compareTo(aux.word.getName()) == 0) //if the word to delete is found 
      { 
       if (aux.next == null) //to erase the last element 
       { 
        prev.next = null; 
        // Takes care of the case of a one-item list 
        aux = null; 
       } 
       else 
       { 
        aux.word.setName(aux.next.word.getName()); //set current node's name to equal next node's 

        WordNode temp = aux.next.next; 
        aux.next = null; //to erase current node 
        aux.next = temp; //re-refer 
       }       
       return true; 
      } 
      else { 
       prev = aux; 
       aux = aux.next; 
     } 

     return false; //reachable if word is not found 
    } 
} 
+0

Это сработало! Но не тогда, когда в списке есть только один элемент. Поэтому я добавил 'if (prev == aux) list = null;' before 'if (aux.next == null)' Я протестировал его и не нашел никаких ошибок, но вы думаете, что я что-то упустил? В любом случае, спасибо, остальная часть кода работает! – gfcf14

+0

Я предлагаю сделать это надлежащим образом, что добавляет «головной» узел. Если то, что вы называете списком, является только первым узлом, и вы устанавливаете его в нуль, тогда ваш список отсутствует. Вы не можете вставлять больше узлов в список, когда-либо. Вы можете _hack_ вашего списка иметь проверку 'if (list == null) {list = newNode}' перед тем, как вставлять новые узлы, чтобы сделать ваш список запущенным снова, если это «null», но дело в том, что он станет новым список и все предыдущие ссылки на него будут по-прежнему оставаться «null», а не отражать изменение вставки нового узла. – marcelv3612

+0

Ах, мое плохое. aux - это копия списка, поэтому установка его в null не влияет на фактический объект списка. Я думаю, что теперь, когда мы сохраняем предыдущий узел, мы можем немного упростить удаление. prev.next = aux.next должен выполнять эту работу. Кроме того, как сказал Марсельв, я бы поставил «голову». Любая достойная реализация списка должна иметь это. – Wehrdo

0

Добавить узел head. Тогда в чеке для последнего узла, вы будете иметь:

if (aux.next == null) //to erase the last element 
{ 
    aux.head.next = null; 
} 
+0

так, должен ли 'head' всегда быть' aux', так как он относится к первому узлу? – gfcf14

Смежные вопросы