[英]Insertion Sort algorithm java doubly linked list
我有一個帶有前哨節點的雙鏈表,我需要使用O(n ^ 2)復雜度的插入排序對其進行排序。 我已經編寫了此代碼,但是它不能按預期的方式工作。
在插入排序方面,特別是在代碼方面,總體上有幫助嗎?
public void insertionSort()
{
int key,i;
int size = getSize();
this.restart();
for(i = 2; i < size; i++)
{
this.next(); // Go to next node
key = this.getVar(); // get the integer a node holds
while(this.hasNext() == 1 && position.prev.var < key && position.var != -1)
{
position.prev.setNext(position.next);
position.next.setPrev(position.prev);
position.setNext(position.prev);
position.setPrev(position.prev.prev);
position.prev.setNext(position);
position.next.setPrev(position);
this.goBack(); // go to the previous node
}
}
}
大小是列表中有多少個元素。 我的前哨有var = -1,所以我想停在頭上時才停下來,這就是為什么要使用它。
position.var != -1
並且this.hasNext() == 1
是正確的,只要我們在一個位置!
在特定的示例中,我的列表中有35個整數:
5 9 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1
我想用這種方式對它們進行排序:
9 5 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
更新:我在插入排序中使用的代碼如下:
public int getSize()
{
int size = 0;
this.restart();
while(this.hasNext() == 1)
{
size++;
this.next();
}
return size;
}
public void restart()
{
position = header;
previous = Sentinel;
}
public void next()
{
previous = position;
position = position.next;
}
public int getVar()
{
return position.var;
}
public void goBack()
{
position = previous;
previous = previous.prev;
}
public int hasNext()
{
if(position.var != -1)
return 1;
else
return 0;
}
public void setNext(Node next)
{
this.next = next;
}
public void setPrev(Node prev){this.prev = prev; }
另外,我使用列表迭代器。
這應該可以解決問題:
int j;
// ...
for(i = 1; i < size; i++)
{
this.restart(); // start at ith node
for(j = 0; j < i; j++)
this.next();
key = this.getVar(); // same code as before
或為每個外部循環使用一次提前一個節點的另一個變量。
另外,難道不能將this.hasNext()重命名為this.hasPrev()嗎?
該代碼的主要部分似乎是正確的,示例圖:
// goal: swap B and C
// initial state
p
-> -> -> ->
A B C D
<- <- <- <-
// remove C from list
position.prev.setNext(position.next);
position.next.setPrev(position.prev);
p
----->
-> -> ->
A B C D
<- <- <-
<----
// update C next and previous
position.setNext(position.prev);
position.setPrev(position.prev.prev);
p
----->
-> -> ->
A C B D
<- <- <-
<----
// insert C into list
position.prev.setNext(position);
position.next.setPrev(position);
p
-> -> -> ->
A C B D
<- <- <- <-
這是我對內循環的分析中的注釋,您說對了,那里肯定有問題。
position.unlink():與眾不同,鄰居成為直接鄰居
position.prev.next = position.next; // TODO 1: position.next.prev = position.prev
position.next.prev = position.prev; // TODO 2: position.prev.next = position.next
^ Breaks TODO 1, but we can: position.prev.next.prev = position.prev
因此,我們仍然需要TODO 1,然后按此順序2:
-- TODO 1: position.prev.next.prev = position.prev
-- TODO 2: position.prev.next = position.next
position.insertBefore(position.prev):重新排隊再排一處
position.next = position.prev; // TODO 3: position.prev.prev = position
position.prev = a = position.prev.prev; // TODO 4: a.next = position
// ^ // same: position.prev.next = position
// | // *Error 1!*
// + breaks TODO's 1 and 2, *Error 2!*
// + breaks TODO 3, but we can instead: position.next.prev = position
關於錯誤1,TODO 3和TODO 4都涉及position.prev
,將它的next
和prev
都設置為position
; 這有效地將position.prev
與position
包圍在一起。 沒有如果步驟向前或向后的事情,這是直接的鄰居將是position
。 經過一步,一切都一樣。 有趣的結構-就像房子的前門和后門都訪問同一位置。
錯誤2使得不可能更新position.prev
,這是需要TODO的1,2和3。 我們仍然可以通過使用替代表達式通過position.prev
的next
字段訪問a.next
來滿足TODO 3 ,但是TODO的1和2將不再滿足。
position.insertBefore(position.prev),繼續:
position.prev.next = position; // DONE: 4
position.next.prev = position; // DONE: 3
這兩行完成了TODO 3和TODO 4,剩下的就是:
-- TODO 1: position.prev.next.prev = position.prev
-- TODO 2: position.prev.next = position.next
-- TODO 5: fix Error 1
-- TODO 6: fix Error 2
修正錯誤1涉及確保TODO 1和2在TODO 4之前完成,修正錯誤2是確保TODO 3在分配a
之前完成。
您最終要完成8項作業; 事后看來,對於雙鏈表和涉及4個節點的運動並不奇怪。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.