一、题目描述
对链表进行插入排序。
插入排序的动画演示如上。从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示)。
每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中。
插入排序算法:
插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
重复直到所有输入数据插入完为止。
示例 1:
输入: 4->2->1->3
输出: 1->2->3->4
示例 2:
输入: -1->5->3->4->0
输出: -1->0->3->4->5
二、代码实现
(1)Java实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode insertionSortList(ListNode head) {
ListNode dummy = new ListNode(0), pre;
dummy.next = head;
while(head != null && head.next != null) {
if(head.val <= head.next.val) {
head = head.next;
continue;
}
pre = dummy;
while (pre.next.val < head.next.val) pre = pre.next;
ListNode curr = head.next;
head.next = curr.next;
curr.next = pre.next;
pre.next = curr;
}
return dummy.next;
}
}
(2)C++实现
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* insertionSortList(ListNode* head) {
ListNode* dummy=new ListNode(-1);
while(head){
ListNode* p=dummy;
while(p->next && p->next->val<head->val) p=p->next;
ListNode* q=head;
head=head->next;
q->next=p->next;
p->next=q;
}
return dummy->next;
}
};
(3)Python实现法一
## 链表排序
class Solution:
def insertionSortList(self, head: ListNode) -> ListNode:
if(head==None or head.next==None):
return head
else:
h=ListNode();h.next=head;
## 增设一个头指针,使得操作一致。
p=head.next;head.next=None
## 第一个节点不用排序,和后面的节点断开;p指向未排序链表的第一个节点
s=h;st=h.next
## 利用插入法进行链表排序。增设两个指针,s和st。
## st指向要与p进行比较的节点,s指向st的前一个节点
while(p!=None):
if(p.val<s.val):
s=h;st=h.next ## 利用上次排序的结果;以减少比较次数
while(st!=None and p.val>st.val):
s=st;st=st.next
## 已经找到位置,进行插入
s.next=p;p=p.next;s.next.next=st;s=s.next
return h.next
(4)Python实现法二
## 数组排序
class Solution:
def insertionSortList(self, head: ListNode) -> ListNode:
## 新开一个列表ans[],把节点值都存入列表ans[]中,然后对列表ans[]进行排序
ans=[];p=head
while(p):
ans.append(p.val)
p=p.next
ans.sort()
## 把排好序的列表ans[]中元素依次赋值给链表中的节点
p=head;m=0
while(p):
p.val=ans[m]
p=p.next;m+=1
return head
三、算法分析
图中分别是四种算法的执行效果。可以看出,有的时候,C++也不一定比Java快,并且链表实现并不一定比数组实现快。
四、算法讲解
算法讲解,我主要参考文献[1]和文献[2],如果想要了解更加深入的话,可以参考文献[1]和文献[2]。
参考文献
[1] https://www.bilibili.com/video/BV1Ti4y187pN/?spm_id_from=autoNext
[2] https://www.bilibili.com/video/BV1KD4y1Q7fH?from=search&seid=6003341128275066300
[3] https://leetcode-cn.com/problems/insertion-sort-list/
[4] https://leetcode-cn.com/problems/insertion-sort-list/comments/