题目
- 对链表进行插入排序
插入排序算法:
插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
重复直到所有输入数据插入完为止。
示例 1:
输入: 4->2->1->3
输出: 1->2->3->4
解析
排序并不陌生,数组可以用冒泡和选择排序法。
排序过程
对于无序单链表,需要将链表拆分,比较。重组形成有序链表。
我们可以采用将头节点取下来,作为新有序链表的头(realhead);
next指向原链表的第二个节点,每完成一次插入排序,next向后走一步,
直到next等于NULL,排序完毕。
插入方式:
小于头节点则头插,头插后后定义新头。
同时记录尾节点(tail),大于尾节点则尾插,尾插后定义新尾巴。
都不满足则为中间(2~n)插入,单链表的中间插入需要记录当前位置和上一个位置的地址,否则会丢失无法链接在一起。用cur和curprev寻找合适的插入位置,next->val小于cur->val时满足插入条件,不满足同时移动一步。
每次中间插入完成后将cur和curprev重新定义,cur是有序链表第二个节点,curprev是有序链表第一个节点。
图解
源代码以及调试应用场景代码
#include<Windows.h>
#include<stdio.h>
#include <assert.h>
#pragma warning (disable:4996)
struct ListNode {
int val;
struct ListNode *next;
};
typedef struct ListNode ListNode;
struct ListNode* insertionSortList(struct ListNode* head){
if (head == NULL)
{
return NULL;
}
ListNode* cur = head;
ListNode*curprev = NULL;
ListNode* next = head->next;
cur->next = NULL;
ListNode* realhead = head;
ListNode* tail = head;
while (next)
{
//头插
if (next->val <= realhead->val)
{
ListNode*temp = next->next;
next->next = realhead;
realhead = next;
next = temp;
curprev = realhead;
cur = curprev->next;
}
//尾插
else if (next->val>tail->val)
{
tail->next = next;
tail = next;
ListNode*temp = next->next;
next->next = NULL;
next = temp;
}
else
//中间插
{
while (next->val > cur->val)
{
curprev = cur;
cur = cur->next;
}
if (next->val <= cur->val)
{
ListNode*temp = next->next;
next->next = cur;
curprev->next = next;
next = temp;
cur = realhead->next;
curprev = realhead;
}
}
}
return realhead;
}
int main()
{
ListNode*n6 = (ListNode*)malloc(sizeof(ListNode));
if (n6)
{
n6->val = 35;
n6->next =NULL;
}
ListNode*n5 = (ListNode*)malloc(sizeof(ListNode));
if (n5)
{
n5->val = 53;
n5->next = n6;
}
ListNode*n4 = (ListNode*)malloc(sizeof(ListNode));
if (n4)
{
n4->val = -24;
n4->next = n5;
}
ListNode*n3 = (ListNode*)malloc(sizeof(ListNode));
if (n3)
{
n3->val = 133;
n3->next = n4;
}
ListNode*n2 = (ListNode*)malloc(sizeof(ListNode));
if (n2)
{
n2->val = 220;
n2->next = n3;
}
ListNode*head = (ListNode*)malloc(sizeof(ListNode));
if (head)
{
head->val = 999;
head->next = n2;
}
ListNode* list = head;
while (head)
{
printf("%10d->", head->val);
head = head->next;
}
printf("NULL\n");
head = list;
while (head)
{
printf("%10p->", head);
head = head->next;
}
printf("NULL\n");
head = list;
ListNode* sortNode = insertionSortList(head);
ListNode* cpylist = sortNode;
while (sortNode)
{
printf("%10d->", sortNode->val);
sortNode = sortNode->next;
}
printf("NULL\n");
sortNode = cpylist;
while (sortNode)
{
printf("%10p->", sortNode);
sortNode = sortNode->next;
}
printf("NULL\n");
system("pause");
}