来自Leetcode第147题对链表进行插入排序
对链表进行插入排序。

插入排序的动画演示如上。从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示)。
每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中。
插入排序算法:
- 插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
- 每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
- 重复直到所有输入数据插入完为止。
示例 1:
1 2
| 输入: 4->2->1->3 输出: 1->2->3->4
|
转换成列表后排序
最简单思路,转换成数组(列表)后直接sort,最后转回链表即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public ListNode insertionSortList(ListNode head) { if(head == null || head.next == null) return head; ListNode p1 = head; List<Integer> list = new ArrayList<>(); while (p1 != null){ list.add(p1.val); p1 = p1.next; } Collections.sort(list); Iterator<Integer> it = list.iterator(); p1 = head; while (it.hasNext()){ head.val = it.next(); head = head.next; } head.next = null; return p1; }
|
插入排序
先假定一个伪头结点,并把尾结点tail设置为伪头结点,接着依次比较当前结点cur与tai的值,如果tail的值大于等于cur,则说明cur应该插入tail之前,先记录下cur.next,并将tail.next设置为cur.next,从伪头结点开始遍历,直到找到一个结点下一个结点的值大于cur,这样就找到了cur结点的插入位置,修改对应结点的位置即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public ListNode insertionSortList(ListNode head) { if(head == null || head.next == null) return head; ListNode p1 = new ListNode(Integer.MIN_VALUE); ListNode pre = p1, tail = p1, cur = head; while(cur != null){ if(tail.val < cur.val){ tail.next = cur; tail = cur; cur = cur.next; }else{ ListNode tmp = cur.next; tail.next = tmp; while (pre.next != null && pre.next.val < cur.val) pre = pre.next; cur.next = pre.next; pre.next = cur; pre = p1; cur = tmp; } } return p1.next; }
|