public void insertSort(int[] nums){
//默认数组第一个数为排好序的所以下标从1开始
for(int i=1,j;i<nums.length;i++){
//存放nums[i],因为后面元素后移过程会被覆盖
int curr=nums[i];
//内部排序好的数组的最后一位需要跟新的比如果比它大 当前元素后移
//因为循环结束后j-- 所以那个空的位置是j+1
for ( j =i-1;j>=0&&nums[j]>curr;j--){
nums[j+1]=nums[j];
}
nums[j+1]=curr;
}
}
举例:
LeetCode 147:
对链表进行插入排序。
插入排序的动画演示如上。从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示)。
每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中。
插入排序算法:
插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
重复直到所有输入数据插入完为止。
示例 1:
输入: 4->2->1->3
输出: 1->2->3->4
示例 2:
输入: -1->5->3->4->0
输出: -1->0->3->4->5
解法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
思路一定不要从从数组中从0开始建立想起这样太复杂且思维会发散,就假设当前链表前半段为排序好的链表,后来的为插入的理解,那么思路就为如下:
用循环找到排序链表的最后一位 为head;
再从排序链表中从头开始找到 pre的下一个节点的值大于head.next的值,这样返回的pre的下一个节点为head节点,因为是链表所以需要curr来标记head的下一个节点的位置,先把head连接到head.next.next,再连接curr
*/
class Solution {
public ListNode insertionSortList(ListNode head) {
ListNode dummy=new ListNode(0);
dummy.next=head;
while(head!=null&&head.next!=null){
if(head.val<head.next.val){
head=head.next;
continue;
}
ListNode pre=dummy;
while(pre.next.val<head.next.val)pre=pre.next;
ListNode curr=head.next;
head.next=head.next.next;
curr.next=pre.next;
pre.next=curr;
}
return dummy.next;
}
}