アイデア:
配列の挿入ソートは、挿入する適切な位置を見つけるために最後のトラバーサルから後ろから前へと行われます。リンクリストは前にトラバースできません。先頭ノードへのポインターが必要で、前から後ろにトラバースします。挿入する適切な位置を見つける
コード:
class Solution {
public ListNode insertionSortList(ListNode head) {
//是return head而不是0
if(head==null) return head;
//只是一个空链表,不带头节点
ListNode hair=new ListNode(0);
hair.next=head;
ListNode lastSorted=head,curr=head.next;
//此处是curr而不是curr.next
while(curr!=null){
//是"<="
if(lastSorted.val<=curr.val){
lastSorted=lastSorted.next;
curr=curr.next;
}else{
//用到的时候再创建,不要一开始就创建。这样可以减少内存开销
ListNode prev=hair;
//是"<="
while(prev.next.val<=curr.val){
prev=prev.next;
}
lastSorted.next=curr.next;
curr.next=prev.next;
prev.next=curr;
//重置,把curr继续放在lastSorted后面,继续遍历
curr=lastSorted.next;
}
}
return hair.next;
}
}
壊す:
1)ヘッドノードのポインタヘア、最後にソートされたcurrが必要です。lastsortedは、ソートされ、内部ループに属する最後の要素と同等です。currは、ソートされておらず、外側のループに属する最初の要素です。PREVをれる前面から背面にループを使用。内側ループの最後の要素は、メモリ消費量を低減し、パフォーマンスを向上させることができ、外側ループの最初の要素よりも大きい場合には、それが作成され
2)内側のループの最後の要素が外側のループの最初の要素よりも小さい場合、両方のポインターが1つ後方に移動します
if(lastSorted.val<=curr.val){
lastSorted=lastSorted.next;
curr=curr.next;
}
3)注文コードを逆にする
ListNode prev=hair;
//是"<="
while(prev.next.val<=curr.val){
prev=prev.next;
}
lastSorted.next=curr.next;
curr.next=prev.next;
prev.next=curr;
//重置,把curr继续放在lastSorted后面,继续遍历
curr=lastSorted.next;