2017-12-13 6 views
2

이 코드는 자바 LinkedList 구현에서 가져온 것입니다.이 메소드는 목록의 색인 포인트에 문자열 요소를 추가하고 내 CS 도서 중 하나에서 가져옵니다.Java Linked List 포인터 혼동

링크 된 목록 클래스는 2 개 글로벌 private 변수

Node first; 
Node last; 


public void add(int index, String e) { 
    if (index < 0 || index > size()) { 
     String message = String.valueOf(index); 
     throw new IndexOutOfBoundsException(message); 
    } 

    // Index is at least 0 
    if (index == 0) { 
     // New element goes at beginning 
     first = new Node(e, first); 
     System.out.println("ran"); 
     if (last == null) 
      last = first; 
     return; 
    } 

    // Set a reference pred to point to the node that 
    // will be the predecessor of the new node 
    Node pred = first; 
    for (int k = 1; k <= index - 1; k++) { 
     pred = pred.next; 
    } 

    // Splice in a node containing the new element 
    pred.next = new Node(e, pred.next); 
    System.out.println(toString()); 

    // Is there a new last element ? 
    if (pred.next.next == null) 
     System.out.println("ran"); 
     last = pred.next; 
} 

내 질문
을 가지고 내가 Node first, last

아래에있는 상태에서 업데이트되는 방법을 이해하지 않습니다

당신이 알을 가지고 있다고 가정 해보십시오. 그런 다음 요소 "4"인덱스에 3

그래서, 목록이 좋아하는 ["1","2","3","4","7","4","5,"6"] 보이는 추가,하지만 추가 방법의 코드를보고하는 나는 방법을 모른다

["1","2","3","7","4","5,"6"]과 같은 표준시 처음으로 또는 마지막 노드 포인터가 업데이트됩니다. 인덱스가 0이 아닌 마지막이 변경되지 않기 때문에 내 마음에 이러한 실행 코드의 유일한 조각 때문에

편집

노드 first는 toString 메소드에서 사용되는 객체 (미도시)를 추가하기 전에 수집

// Set a reference pred to point to the node that 
    // will be the predecessor of the new node 
    Node pred = first; 
    for (int k = 1; k <= index - 1; k++) { 
     pred = pred.next; 
    } 
    // Splice in a node containing the new element 
    pred.next = new Node(e, pred.next); 
    System.out.println(toString()); 
+0

분명히하려면이 추가 메서드를 테스트하고 작동하지 않았다. – cheesey

답변

0

통해 통과하는 첫 번째 요소는 "1"과 마지막 요소는 "6"이다.
추가 후 첫 번째 요소는 "1"이고 마지막 요소는 "6"입니다.
첫 번째마지막은 변경되지 않습니다. 첫 번째 요소 또는 마지막 요소를 변경하지 않았으므로 필요하지 않습니다.

+0

글쎄, 이걸 테스트 해본 결과, 10 개의 엘리먼트로 목록을 채운 다음 인덱스 6에 값을 추가하고 노드를 처음 사용하는 toString 메소드를 실행하여 컬렉션을 트래버스했다. 출력은 정확했지만 첫 번째 노드 객체가 어떻게 업데이트되었는지 잘 모르겠습니다. – cheesey

0

이 링크 된 목록 구현 방식으로 인해 수렁에 빠지고 있다고 생각합니다. firstlast 포인터가있어 목록의 시작과 끝만 추적합니다. 따라서 목록의 중간에 요소를 삽입하면 이러한 포인터가 업데이트되지 않으며 이러한 업데이트가 필요하지 않습니다. 그러나 그들은 을 수행합니다.은 현재 헤드 앞 또는 목록의 현재 꼬리 뒤의 토큰을 삽입해야 업데이트됩니다. 여기

if (index == 0) { 
    // New element goes at beginning 
    first = new Node(e, first); 
    System.out.println("ran"); 
    if (last == null) 
     last = first; 
    return; 
} 

임계 선 사실이있다 : 여기에 헤드 삽입을 처리하는 코드는

first 포인터는 새로운 노드에 할당됩니다
first = new Node(e, first); 

턴 지점에서 이전에있는 first 노드.마찬가지로,리스트의 마지막에 새로운 노드 땅의 삽입, 다음 코드는이를 처리해야한다 : 여기

if (pred.next.next == null) { 
    System.out.println("ran"); 
    last = pred.next; 
} 

last 포인터가 이전 last를 삽입 된 새로운 노드에 할당 .

그러나이 두 가지 경우 이외에 삽입으로 firstlast을 업데이트 할 필요가 없습니다.

+0

** 첫 번째 ** 노드 목록에있는 다른 모든 노드에 대한 참조로 생각하고 소스 코드의 다른 부분에있는 toString 메서드를 생성하는 데 사용할 수 있지만 행에는 ** first = 새로운 노드 (e, first); ** – cheesey

+0

'첫 번째 또는 마지막 노드 포인터가 어떻게 갱신되는지 모르겠다. '... 나는이 지식에 대한 나의 질문에 대답했다. 왜 '첫 번째'포인터와 '마지막 포인터'를 유지해야하는지에 대한 논의가 필요하다면, 나중에 두 번째 질문이 될 수도 있습니다. –

0

인덱스가 0이면 노드가 beginnng에 추가되고 for 루프가 작동하지 않습니다. 1이면 루프가 다시 실행되지 않고 노드가 목록에 추가됩니다. 그러나 다른 것이 있으면 index-1 위치에 도달 할 때까지 루프는 각 요소를 한 단계 뒤로 이동시킵니다. 그런 다음 루프 외부의 코드 (새 요소가 포함 된 노드에서 조각으로 나눕니다)는 요소를 index에 삽입합니다. 루프가 실행 된 후 인덱스가 마지막 노드로 판명되면 마지막 노드가 업데이트됩니다.

희망이 도움이됩니다.