LeetCode第147题单链表的插入排序
题目描述:
对链表进行插入排序。
插入排序算法:
插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
重复直到所有输入数据插入完为止。
示例 1:
输入: 4->2->1->3
输出: 1->2->3->4
示例 2:
输入: -1->5->3->4->0
输出: -1->0->3->4->5
刚学习完数据结构,一开始是完全自己摸索着去写排序,写了很长一堆,然后通过研究其他人的解决思路完善了代码,一共提交了三次,共三个版本的代码。
版本一在思路上是直接对原始链表操作,对于待排序元素不仅要求找到合适的位置进行插入而且还需要对待排序元素在原位置进行删除。
版本二和版本三是使用了拆分的思路,把原链表进行拆分成已经排好序的部分和待排序的部分。区别是版本三的代码引入了头结点简化了代码。
代码三写了注释,所以就先放代码三的:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* insertionSortList(struct ListNode* head){
struct ListNode *p = head->next; //插入排序从第二个结点开始
struct ListNode *pre,*q;
//pre:用于插入排序遍历前面没已经排好的有序序列的指针,q用来保存执行过程中p的下一个结点
struct ListNode *L = (struct ListNode*) malloc(sizeof(struct ListNode));
//L:头指针
L->next=head;
L->next->next = NULL; //初始化有序链表,目前排好的有序链表只有第一个元素
while(p!=NULL){
q=p->next;
//由于p的next指针会在接下来运行过程中发生变化,因此循环开始就用q指向p的下一个指针
pre=L;
//重置基准结点(基准结点指用来遍历排完序部分链表的指针
while(pre!=NULL){
if( pre->next==NULL || pre->next->val > p->val ){
//由于基准结点从头指针开始遍历,当基准结点的下一个元素大于待排序元素进行后插
//当基准结点遍历到最后一个时,证明所有元素都小于待排序元素,直接将元素进行尾插
p->next=pre->next;
pre->next = p;
break;
}
else
pre=pre->next;
}
p=q; //待排序元素后移
}
return L->next;
}
接下来是不使用头指针的版本二:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* insertionSortList(struct ListNode* head){
struct ListNode *p = head->next;
struct ListNode *L=head;
struct ListNode *pre;
L->next = NULL;
while(p!=NULL){
struct ListNode *temp = (struct ListNode*) malloc(sizeof(struct ListNode));
pre=L;
while(pre!=NULL){
if(pre->val > p->val){
temp->val = pre->val;
temp->next =pre->next;
pre->val = p->val;
pre->next = temp;
break;
}
else if(pre->next==NULL){
temp->val = p->val;
temp->next =pre->next;
pre->next=temp;
break;
}
else
pre=pre->next;
}
p=p->next;
}
return head;
}
最后是版本三:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* insertionSortList(struct ListNode* head){
struct ListNode* p = head->next;
int del = 0;
while(p!=NULL){
del =0 ;
struct ListNode* q = (struct ListNode*) malloc(sizeof(struct ListNode));
struct ListNode *temp = (struct ListNode*) malloc(sizeof(struct ListNode));
if(head->val > p->val){
temp->val = p->val;
if (p->next!=NULL){
p->val = p->next->val;
p->next = p->next->next;
del =1;
}
else{
struct ListNode *m = head;
while(m->next->next!=NULL){
m=m->next;
}
m->next=NULL;
del =0;
}
temp->next = head;
head = temp;
if(del==0){p=p->next;}
else p=p;
continue;
}
else{
q->next = head;
while(q->next!=p){
if(q->next->val > p->val){
temp->val = p->val;
if (p->next!=NULL){
p->val = p->next->val;
p->next = p->next->next;
del=1;
}
else{
struct ListNode *m = head;
while(m->next->next!=NULL){
m=m->next;
}
m->next=p->next;
del=0;
}
temp->next = q->next;
q->next = temp;
break;
}
else
q = q->next;}
if(del==0){p=p->next;}
else p=p;
}}
return head;
}