对链表进行插入排序。
插入排序的动画演示如上。从第一个元素开始,该链表可以被认为已经部分排序(用黑色表示)。
每次迭代时,从输入数据中移除一个元素(用红色表示),并原地将其插入到已排好序的链表中。
147. 对链表进行插入排序
插入排序算法:
插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
重复直到所有输入数据插入完为止。
示例 1:
输入: 4->2->1->3
输出: 1->2->3->4
示例 2:
输入: -1->5->3->4->0
输出: -1->0->3->4->5
解题
若在原链表上改动,每次遍历链表都不相同,故采用新建表头,返回新链表;
新建链表
新建链表表头,head记录正在添加的链表节点,每次遍历新链表,将节点插入next->val不存在或者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) {
ListNode dummy(0);
ListNode * p=&dummy;
ListNode * cur=p;
ListNode *next;
while(head){
next=head->next;
if(!cur->next||cur->next->val>head->val){
ListNode *tmp=cur->next;
cur->next=head;
cur->next->next=tmp;
head=next;
cur=p;
}
else cur=cur->next;
}
return dummy.next;
}
};
优化1:每次cur与head下一个比较,若head大的话从当前cur搜索即可,无需从头搜索;
class Solution {
public:
ListNode* insertionSortList(ListNode* head) {
ListNode dummy(0);
ListNode * p=&dummy;
ListNode * cur=p;
ListNode *next;
while(head){
next=head->next;
if(!cur->next||cur->next->val>head->val){
ListNode *tmp=cur->next;
cur->next=head;
cur->next->next=tmp;
head=next;
if(!head||head->val<cur->val) cur=p; //小的话从头搜索 大的话从当前搜索
}
else cur=cur->next;
}
return dummy.next;
}
};
注意点
构建dummyhead并不会使用额外空间!
只用了一个头节点的空间;