对链表进行插入排序。
插入排序的动画演示如上。从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示)。
每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中。
插入排序算法:
- 插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
- 每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
- 重复直到所有输入数据插入完为止。
示例 1:
输入: 4->2->1->3 输出: 1->2->3->4
示例 2:
输入: -1->5->3->4->0 输出: -1->0->3->4->5
思路:在两个链表上进行操作。一个是原本的链表,再新定义一个链表。对就链表逐个遍历,按照插入排序的方式插入新的链表中。
1 /** 2 * Definition for singly-linked list. 3 * public class ListNode { 4 * int val; 5 * ListNode next; 6 * ListNode(int x) { val = x; } 7 * } 8 */ 9 class Solution { 10 public ListNode insertionSortList(ListNode head) { 11 //基本思想:遍历旧链表,插入新链表 12 //建立新的链表:只要有个头就可以了 13 ListNode newHead = null; 14 //在遍历新的链表中没移动一次需要记住前驱 15 ListNode pre = null; 16 //旧链表中取出来的待排序的结点 17 ListNode wait = null; 18 //新链表中和待排序结点比较的当前结点 19 ListNode cur = null; 20 //考虑输入的链表为空的情况 21 if(head == null) 22 return null; 23 //输入的链表不是空的,就开始遍历并插入新的链表,用while循环比较好,遍历只能从前往后 24 while(head!=null){ 25 wait = head; 26 head = head.next; 27 wait.next = null; 28 if(newHead == null){ 29 newHead = wait; 30 } 31 else{ 32 cur = newHead; 33 while(wait.val >= cur.val&&cur.next!=null){ 34 pre = cur; 35 cur = cur.next; 36 } 37 //插在链表的头部 38 if(cur==newHead){ 39 if(wait.val<cur.val){ 40 wait.next = cur; 41 newHead = wait; 42 } 43 else{ 44 cur.next = wait; 45 } 46 } 47 else{ 48 //插在链表的尾部 49 if(cur.next==null&&wait.val>=cur.val){ 50 cur.next = wait; 51 } 52 else{ 53 pre.next = wait; 54 wait.next = cur; 55 } 56 } 57 } 58 } 59 return newHead; 60 } 61 }
总结:这是最笨的一种方法。暴露的问题是你对链表的及其不了解和不熟悉。里面有很多默认的东西以及很多对于完成题目来说的基础的概念和认识需要加强。