对链表进行插入排序。链表为无头结点、单向、不循环。(由于涉及到结构体,所以写不了完整的测试代码,下面展示的代码为LeetCode中写的代码)

1.插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
2.每次迭代中,插入排序只从输入数据中移除一个待排序的元素,从有序序列的最后一个位置开始向前遍历,找到它在序列中适当的位置,将其插入。
3.重复直到所有输入数据插入完为止。

//第一次尝试:
//方法:由于所给的链表是单向的,所以上面所说的从后向前遍历是不能实现的,所以我们只能从待排序的序列中拿出一个元素,然后在前面的有序序列中从头遍历,找到一个合适的位置插入
// 由于头结点前面的插入和其他位置的插入是不一样的,所以要分情况讨论,但是我们可以使用虚空大法,先创建一个虚头结点,然后将两种情况合二为一,然后进行排序,最终只需返
// 虚头结点的下一个结点即可
struct
ListNode* insertionSortList(struct ListNode* head){
//参数合法性检验,最起码要有两个元素才能排序
if(head == NULL||head->next == NULL){ return head; }
//设置虚头结点
struct ListNode list; list.next = head; struct ListNode* tail = head; struct ListNode* cur = tail->next; while(cur){
//这我们可以先设置一个筛选器,如果待排序的元素比有序序列的最后一个元素都大,那就不需排序了,直接更新变量即可
if(cur->val >= tail->val){ tail = tail->next; cur = cur->next; } else{ struct ListNode* node = cur; cur = cur->next; tail->next = cur; struct ListNode* swap = list.next;
//这个last指针是用来保存swap的上一个结点
struct ListNode* last = &list;
//while里的条件一定是swap不等于tail的后一个结点,如果是swap != tail的话,那么将会少考虑一种情况:待排序结点在有序序列尾结点的前一个位置,也就是tail前一个位置
while(swap != cur){
//找到合适的位置,将其插入,然后结束循环
if(swap->val >= node->val){ last->next = node; node->next = swap; break; }
//更新变量 last
= swap; swap = swap->next; } } } return list.next; }