对链表进行插入排序。
插入排序的动画演示如上。从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示)。
每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中。 插入排序算法:
插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。 重复直到所有输入数据插入完为止。
示例 1:
输入: 4->2->1->3 输出: 1->2->3->4
示例 2:
输入: -1->5->3->4->0 输出: -1->0->3->4->5
对链表进行插入排序,排序过程没什么可说的,这里主要注意几个技巧,首先对链表进行排序处理,因此最后的输出节点不一定是初始的head节点,这时通常需要哑节点记录头节点信息,最后返回哑节点的下一个节点即可。插入操作是在某节点后进行插入,因此通常需要记录下插入位置的前一节点,这时的通常操作是对节点的下一个节点进行判断,eg:while(temp->next->val…),这样可以找到插入节点的前一节点位置。代码如下:
/**
* 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) {
if(!head || !head->next)return head;
//创建哑节点,这步是必须的
ListNode* dummy=new ListNode(-1);
dummy->next=head;
ListNode* pre=head;
ListNode* cur=head->next;
while(cur){
if(cur->val<pre->val){
//寻找插入点时通常需要找到前一节点位置,因此判断时需要利用下一节点的值进行选择
ListNode* temp=dummy;
while(temp->next->val<cur->val){
temp=temp->next;
}
//插入
pre->next=cur->next;
cur->next=temp->next;
temp->next=cur;
cur=pre->next;
}
else{
pre=pre->next;
cur=cur->next;
}
}
return dummy->next;
}
};