Я смотрю, как вставить новый узел перед первым узлом двусвязного списка. Меня путают вспомогательные узлы, необходимые для этой операции, и последовательность шагов , в которой выполняется операция. Буду признателен за подсказку, как решить эту проблему, т.е. что не так с моим методом insertBeforeFirst
. В его нынешнем виде метод вызывает исключение nullPointerException, которое мне трудно устранить. (примечание: это продолжение предыдущего сообщения .)
Я смотрю, как вставить новый узел перед первым узлом двусвязного списка. Меня путают вспомогательные узлы, необходимые для этой операции, и последовательность шагов , в которой выполняется операция. Буду признателен за подсказку, как решить эту проблему, т.е. что не так с моим методом insertBeforeFirst
. В его нынешнем виде метод вызывает исключение nullPointerException, которое мне трудно устранить. (примечание: это продолжение предыдущего сообщения .)
Я смотрю, как вставить новый узел перед первым узлом двусвязного списка. Меня путают вспомогательные узлы, необходимые для этой операции, и последовательность шагов , в которой выполняется операция. Буду признателен за подсказку, как решить эту проблему, т.е. что не так с моим методом insertBeforeFirst
. В его нынешнем виде метод вызывает исключение nullPointerException, которое мне трудно устранить. (примечание: это продолжение предыдущего сообщения .)
что не так с моим методом insertBeforeFirst
. В его нынешнем виде метод вызывает исключение nullPointerException, которое мне трудно устранить. (примечание: это продолжение предыдущего сообщения .)
что не так с моим методом insertBeforeFirst
. В его нынешнем виде метод вызывает исключение nullPointerException, которое мне трудно устранить. (примечание: это продолжение предыдущего сообщения .)
public DLL()
{
header = null ;
tail = null ;
}
...
DLL myList = new DLL() ;
DLLNode A = new DLLNode("Hello", null, null) ;
DLLNode B = new DLLNode("Hi", null, null) ;
...
myList.addFirst(A) ;
myList.insertBeforeFirst(B)
...
public void addFirst(DLLNode v)
{
v.pred = header ;
v.succ = tail ;
header = v ;
tail = v ;
}
...
public void insertBeforeFirst(DLLNode v)
{
DLLNode aux = v ;
aux.succ = header.succ ;
header = aux ;
DLLNode aux2 = aux.succ ;
aux2.pred = v ;
}
[РЕДАКТИРОВАТЬ]
Я последовал совету Аарона и сделал рисунок, и у меня есть небольшое улучшение в том, что я больше не получаю nullPointerException, но новый режим вставляется после первого узла, а не перед. Так что мои навыки рисования тоже нуждаются в полировке, я думаю :)
public void insertBeforeFirst(DLLNode v)
{
v.succ = header.succ ; // point new node succ to current first node
header.succ = v ; //point header to new node
DLLNode aux = header.succ ; // auxiliary node for backward insertion
aux.pred = v ; // point auxiliary's pred backward to new node
}
[EDIT2]
Глядя на сообщение MahlerFive, теперь я понимаю, почему некоторые из вас могут запутаться в моем заголовке и заключительной речи. Вот откуда я его взял: «Для упрощения программирования удобно добавлять специальные узлы на обоих концах двусвязного списка: узел заголовка , непосредственно перед заголовком списка, и узел трейлер сразу после хвоста списка. Эти "фиктивные" узлы не хранят никаких элементов " source
Так что, похоже, что для начала мне нужно найти способ реализовать эти фиктивные узлы правильно, прежде чем я смогу что-либо добавить и сделать правильные ссылки. эти DUMMY узлы, похоже, требуют другого конструктора узла? Могут ли они быть созданы конструктором DLL по умолчанию?
[EDIT3]
@MahlerFive, конструктор DLL будет выглядеть так:
public DLL()
{
DLLNode Header = new DLLNode(null, null, null) ;
DLLNode Tail = new DLLNode(null, Header, null) ;
Header.succ = Tail ;
}
и мой метод примерно так, хотя сейчас я получаю исключение nullPointerException:
// insert z before v
public void addBeforeFirst(DLLNode v, DLLNode z)
{
DLLNode aux = v.pred ;
z.pred = aux ;
z.succ = v ;
v.pred = z ;
aux.succ = z ;
}
[EDIT4]
Я добиваюсь прогресса. (Отличное чувство!) Я согласен с MahlerFive в том, что узлы DUMMY Header и Tail не лучший способ приблизиться к этому. Но, как упоминалось в опубликованной книге по этому поводу, стоит хотя бы изучить. Вот мой новый код (без использования фиктивных узлов):
...
// DLL Constructor
public DLL()
{
first = null ;
last = null ;
}
...
// example insert call
// B is the node in front of which i want to insert
l.insert("Ciao", B) ;
...
public void insert(String elem, DLLNode pred)
{
// make ins a link to a newly-created node with element elem,
// predecessor null, and successor null.
DLLNode ins = new DLLNode(elem, null, null) ;
// Insert ins at the insertion point in the
// forward SLL headed by first.
ins.pred = first ;
ins.succ = first ;
// let first be the the new node
first = ins ;
}
это требует точной настройки, поскольку я еще не установил никаких обратных ссылок, но это отличная отправная точка. Чтобы убедиться, что это работает правильно (по крайней мере, в прямом направлении), я добавил операторы печати, чтобы распечатать первый и последний элемент, когда я добавил узлы. Действительно, они обновлялись правильно:
Hi
first: hi
last: hi
Ciao Hi
first: Ciao
last: hi
Moin Ciao Hi
first: Moin
last: hi