2013-10-20 211 views
2

我正在編寫一個doubley鏈接列表數據結構的方法,它應該將參數中指定的從索引a到b的元素列表顛倒過來,並決定去做遞歸。該任務的目標是使用節點練習指針操作。我的方法邏輯對我來說似乎沒有問題,但是當我通過JUnit測試運行代碼時,它不會結束。認爲這很奇怪,我添加了println語句來查看它到達的代碼的哪些部分;一切檢查出好。因此,我通過Eclipse的調試器運行它,並在前進並返回所有遞歸調用之後到達結束括號,而不終止。它只是坐在終端支架上,我以前從來沒有見過這樣的東西。爲什麼這樣做,我該怎麼做才能解決它?Java遞歸方法結束但並沒有終止

下面的代碼:

public void reverseList(int start, int end) 
{ 
    if (start >= end) 
    { 
     return; 
    } 

    ListNode left = getListNode(start); 
    ListNode right = getListNode(end); 
    ListNode leftNext = left.next; 
    ListNode leftPrev = left.previous; 
    ListNode rightNext = right.next; 
    ListNode rightPrev = right.previous; 

    leftPrev.next = right; 
    rightPrev.next = left; 
    leftNext.previous = right; 
    rightNext.previous = left; 
    left.next = rightNext; 
    left.previous = rightPrev; 
    right.next = leftNext; 
    right.previous = leftPrev; 

    reverseList(start + 1, end - 1); 
} 

編輯:這裏是代碼來測試它

的JUnit:

@Test 
public void testReveseList() 
{ 
StudentList list = new StudentList(); 
list.add("a", ""); 
list.add("b", ""); 
list.add("c", ""); 
list.add("d", ""); 
list.add("e", ""); 
list.add("f", ""); 
list.add("g", ""); 
list.add("h", ""); 
list.add("i", ""); 
list.add("j", ""); 
list.printlist(); 
list.reverseList(2, 5); 
System.out.println(); 
StudentList expectedList = new StudentList(); 
expectedList.add("a", ""); 
expectedList.add("b", ""); 
expectedList.add("f", ""); 
expectedList.add("e", ""); 
expectedList.add("d", ""); 
expectedList.add("c", ""); 
expectedList.add("g", ""); 
expectedList.add("h", ""); 
expectedList.add("i", ""); 
expectedList.add("j", ""); 
assertEquals(expectedList, list); 
list.reverseList(2, 5); 

System.out.println(); 

StudentList expectedList1 = new StudentList(); 
expectedList1.add("a", ""); 
expectedList1.add("b", ""); 
expectedList1.add("c", ""); 
expectedList1.add("d", ""); 
expectedList1.add("e", ""); 
expectedList1.add("f", ""); 
expectedList1.add("g", ""); 
expectedList1.add("h", ""); 
expectedList1.add("i", ""); 
expectedList1.add("j", ""); 
assertEquals(expectedList1, list); 
list.reverseList(0, 9); 
System.out.println(); 
StudentList expectedList2 = new StudentList(); 
expectedList2.add("j", ""); 
expectedList2.add("i", ""); 
expectedList2.add("h", ""); 
expectedList2.add("g", ""); 
expectedList2.add("f", ""); 
expectedList2.add("e", ""); 
expectedList2.add("d", ""); 
expectedList2.add("c", ""); 
expectedList2.add("b", ""); 
expectedList2.add("a", ""); 
assertEquals(expectedList2, list); 

} 

測試類:

public class StudentList 
{ 
private ListNode head = null; 

public void add(StudentData data) 
{ 
    ListNode newNode = new ListNode(data); 
    ListNode lastNode = getTail(); 

    if (lastNode == null) 
    { 
     head = newNode; 
    } 
    else 
    { 
     lastNode.next = newNode; 
    } 

    newNode.previous = lastNode; 
    newNode.next = null; 

}  

    public ListNode getListNode(int indexOfDesiredNode) 
{ 
    if (indexOfDesiredNode >= size()) 
    { 
     // --- Error: There aren't that many nodes 
     return null; 
    } 

    // --- Move through the list, node by node, until we find 
    // --- the one we want 
    int count = 0; 
    ListNode current = head; 
    while ((count < indexOfDesiredNode) && (null != current)) 
    { 
     current = current.next; 
     count = count + 1; 
    } 

    // --- So, did we find anything? 
    if (null == current) 
    { 
     // --- Error: We didn't find the node 
     return null; 
    } 

    return current; 
} 

    public int size() 
{ 
    if (null == head) 
    { 
     return 0; 
    } 

    int count = 0; 
    ListNode current = head; 
    while (current != null) 
    { 
     count = count + 1; 
     current = current.next; 
    } 
    return count; 
} 

    public void reverseList(int start, int end) 
{ 
    if (start >= end) 
    { 
     return; 
    } 

    ListNode left = getListNode(start); 
    ListNode right = getListNode(end); 
    ListNode leftNext = left.next; 
    ListNode leftPrev = left.previous; 
    ListNode rightNext = right.next; 
    ListNode rightPrev = right.previous; 

    leftPrev.next = right; 
    rightPrev.next = left; 
    leftNext.previous = right; 
    rightNext.previous = left; 
    left.next = rightNext; 
    left.previous = rightPrev; 
    right.next = leftNext; 
    right.previous = leftPrev; 

    //-- The easy way of doing it... *sigh* 
    // StudentData temp = get(start); 
    // getListNode(start).data = getListNode(end).data; 
    // getListNode(end).data = temp; 

    reverseList(start + 1, end - 1); 
} 
} 

而且ListNode類:

public class ListNode 
{ 
public StudentData data = null; 
public ListNode next = null; 
public ListNode previous = null; 

public ListNode(StudentData data) 
{ 
    this.data = data; 
} 

@Override 
public String toString() 
{ 
    return data.toString(); 
} 
} 

對不起,格式化不是最大的,發生在複製&粘貼。

+0

它應該工作。問題可能出現在getListNode調用中。你可以發佈[SSCCE](http://sscce.org/)嗎? – BackSlash

+0

這是一個尾遞歸函數;所以在最後一次遞歸調用實際返回之後,您只需通過到達函數結尾來隱式地從每個後續調用返回。你確定它永遠不會終止? – chepner

+0

getListNode是我的老師寫的,所以我很積極。它只是返回指定索引處的節點。 – TheBrogrammer

回答

0

問題出在end == start + 1,因此rightPrev == left的情況。然後您設置rightPrev.next = left這使您的列表循環,因此getListNode不會終止。