对链表进行插入排序
提示:对于LeetCode所给出的这个动图来说,只适合数组的插入,不适合单链表的插入排序。
解题思路:把第一个当做有序的结点,剩下的一次拿下来头插或者尾插或者中间插三种情况,当你拿下来的时候一定要记得保留下一个结点地址,否则你插完一个之后就找不到下一个了。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
//只有第一个数有序,其他的数只要比他小,就不断的往前插
//但是这个题所画的动图是不适合链表的插入的,这个动图只适合数组的插入
typedef struct ListNode Node;
struct ListNode* insertionSortList(struct ListNode* head){
if(head == NULL || head->next == NULL)
return head;
//如果链表是空的,那么你直接访问就会崩
Node* sortHead = head;
Node* cur = head->next;
sortHead->next = NULL;
while(cur)
{
//一定要先保存它的下一个,不然就找不到了
Node* next = cur->next;
//把cur插入到sortHead链表中,并且保持有序
//一共有三种情况,第一种是比sortHead小,那么就是头插;第二种就是我比sortHead大那就是尾插,第三种情况就是已经尾插了一个之后,还有一个介于sortHead和尾插的那个结点值之间(中间插)
if(cur->val <= sortHead->val)
{
//头插
cur->next = sortHead;
sortHead = cur;
}
else
{
//中间插
Node* sortPrev = sortHead;
Node* sortCur = sortPrev->next;
while(sortCur)
{
if(cur->val <= sortCur->val)
{
sortPrev->next = cur;
cur->next = sortCur;
break;
}
else
{
sortPrev = sortCur;
sortCur = sortCur->next;
}
}
//这里从循环里面出来可能有两种情况,一种是break,一种是sortCur为NULL,所以需要判断一下
//尾插
if(sortCur == NULL)
{
sortPrev->next = cur;
cur->next = NULL;//只要是尾插一定要记住把它置空,否则就会变成一个环,
}
}
cur = next;
}
return sortHead;
}