题目描述
给定单个链表的头 head
,使用 插入排序 对链表进行排序,并返回 排序后链表的头 。
插入排序 算法的步骤:
- 插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
- 每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
- 重复直到所有输入数据插入完为止。
下面是插入排序算法的一个图形示例。部分排序的列表(黑色)最初只包含列表中的第一个元素。每次迭代时,从输入数据中删除一个元素(红色),并就地插入已排序的列表中。
对链表进行插入排序。
示例:
输入: head = [4,2,1,3] 输出: [1,2,3,4]
题目分析
根据题目分析可以采取双指针的方法(end,current),end的下一个节点为current,比较end与current的值。
当end的值小于等于current的值时,直接将end指针移动到下一个节点,curent随后移动到end指针的后面,继续循环判断即可
当end的值大于current时,需要创建一个虚拟节点进行循环链表,直到虚拟节点的下一个节点的值大于current时,将current插入虚拟指针的后方即可,之后对链表进行排序操作即可
java解法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode insertionSortList(ListNode head) {
if(head == null) return head;
//创建整个链表的虚拟节点,方便后续进行返回操作
ListNode pre = new ListNode(0,head);
//创建两个节点 curent待插节点
ListNode end = head,current = head.next;
while(current != null){
//当end小于等于current时,直接继续循环即可
if(end.val <= current.val){
end = end.next;
}else{
//创捷虚拟节点
ListNode node = pre;
//循环操作,找到current应该插入的位置
while(node.next.val <= current.val){
node = node.next;
}
//修改链表的排序
end.next = current.next;
current.next = node.next;
node.next = current;
}
//每次操作后都将current指向end的后面
current = end.next;
}
//返回整个链表
return pre.next;
}
}