2009-05-14 2 views
1

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

Вопрос заключается в следующем:

сделать то, что окончательный связанный после этого кода:

ListNode n1 = new ListNode(); 
ListNode n2 = new ListNode(); 
ListNode n3 = n1; 
n1.next = n2; 
n3.prev = n1; 
n1.next.prev = n3.next; 

Где заблудились это последняя строка кода.

n1.next.prev = n3.next;

вот решение:

http://www.imagechicken.com/viewpic.php?p=1242322384048558300&x=jpg

кто может ходить мне через это или привести меня в правильном направлении?

+1

Эта строка, которую вы не понимаете, устанавливает n2.prev для себя. Все узлы предыдущих членов указывают на себя. Следующие члены n1 и n3 указывают на n2. Следующий член n2 не определен. –

+0

Думаю, вам нужно дать немного больше информации по этому вопросу - я не уверен, о чем вы спрашиваете? Почему бы вам не понять, почему работает n1.next.prev = n3.next? Это касается смешения l-значений и r-значений (основная причина для путаницы при изучении указателей)? У вас есть правильная иллюстрация, связанная (вы могли бы включить это и в вопрос). – jamuraa

ответ

3

Ключом к этому является то, что n1 и n3 указывают на тот же ListNode.

Вот состояния после каждого из 3-х операций:

n1.next = n2; 
// n1.prev = null; 
// n1.next = n2; 
// n2.prev = null; 
// n2.next = null; 
// n3.prev = null; 
// n3.next = n2; 

n3.prev = n1; 
// n1.prev = n1; 
// n1.next = n2; 
// n2.prev = null; 
// n2.next = null; 
// n3.prev = n1; 
// n3.next = n2; 

n1.next.prev = n3.next; 
// n1.prev = n1; 
// n1.next = n2; 
// n2.prev = n2; 
// n2.next = null; 
// n3.prev = n1; 
// n3.next = n2; 

Так что в последнем заявлении, n3.next такое же, как n1.next, который n2. Таким образом, последний оператор эквивалентен настройкам n2.prev = n2.

0

Я бы попробовал рисовать три коробки. Разделите каждую коробку на треть - одну треть для метки, одну треть для «prev» и одну треть для «следующей». Затем нарисуйте соединительные линии со всех «prev» и «next» на соответствующую метку, чтобы увидеть, как все связано.

Изображение может стоить тысячи слов.

+1

Две коробки, вероятно, упростит работу, поскольку n1 и n3 - это просто разные имена для одного и того же узла. –

0

Такое поведение становится путаным, пока вы не поймете, что есть только два INSTANES списка ListNode; n1, n2 и n3 ссылаются на эти экземпляры. И, в частности, значения n1, n2 и n3 устанавливаются только один раз; поскольку значение n3 установлено в n1, вы можете так же легко заменить n3 на n1 в этом коде, и он будет работать одинаково.

0

Извините, из-за этого изображения не могут быть сделаны из головы или хвоста.

n1.next = n2. Поэтому n1.next.prev оценивает до n2.prev

n3 = n1. Следовательно, n3.next вычисляет значение n1.next.

Вы устанавливаете n2.prev на n1.next.

4

Шаг первый: два узла, не связаны. n1 также известен как n3.

 
     +-------+next  +-------+next 
     |  +---->  |  +----> 
    prev| n1 |  prev| n2 |  
<----+ n3 |  <----+  | 
     +-------+   +-------+ 

Шаг два: n1.next = n2;

 
     +-------+next  +-------+next 
     |  +----------->|  +----> 
    prev| n1 |  prev| n2 |  
<----+ n3 |  <----+  | 
     +-------+   +-------+ 

Шаг три: n3.prev = n1;
Поскольку n3 является n1, это превращает стрелку вокруг.

 
     +-------+next  +-------+next 
     |  +----------->|  +----> 
    prev| n1 |  prev| n2 |  
/----+ n3 |  <----+  | 
\--->+-------+   +-------+ 

Шаг четыре: n1.next.prev = n3.next;
Помните, что n1.next является n2 и n3 является n1. Следуйте стрелки:

 
     +-------+next  +-------+next 
     |  +----------->|  +----> 
    prev| n1 |  prev| n2 |  
/----+ n3 |  /----+  | 
\--->+-------+  \--->+-------+ 

Так prev указатели n1 и n2 и в конечном итоге, указывая на себя.