Insertion Sort List
Sort a linked list using insertion sort.
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* insertionSortList(struct ListNode* head) { struct ListNode *p = head; struct ListNode *tmp = NULL, *min = NULL; int a; if(head == NULL) return NULL; else if(head->next == NULL) return head; while(p->next != NULL) { min = p; tmp = p->next; while(tmp != NULL) { if(tmp->val < min->val) min = tmp; tmp = tmp->next; } a = min->val; min->val = p->val; p->val = a; 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 *cur = head; struct ListNode *helper = malloc(sizeof(struct ListNode)); struct ListNode *pre; helper->next = NULL; if(head==NULL || head->next==NULL) return head; while(cur) { struct ListNode *next = cur->next; pre = helper; while(pre->next != NULL && pre->next->val < cur->val) pre = pre->next; cur->next = pre->next; pre->next = cur; cur = next; } return helper->next; }
- 辅助指针来做表头避免处理改变head的时候的边界情况
- 一个指针指向目标链表,然后逐个取出,和已经在辅助指针所带领的链表中的值对比,找到第一个大于链表中的位置时停止,把该值插入进去
- 标准的插入排序,只是在数组中从后向前比较插入,这里从头到尾比较插入
/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ struct ListNode* insertionSortList(struct ListNode* head) { struct ListNode* new_head = malloc(sizeof(struct ListNode)); new_head -> next = head; struct ListNode* pre = new_head; struct ListNode* cur = head; while (cur) { if (cur -> next && cur -> next -> val < cur -> val) { while (pre -> next && pre -> next -> val < cur -> next -> val) pre = pre -> next; /* Insert cur -> next after pre.*/ struct ListNode* temp = pre -> next; pre -> next = cur -> next; cur -> next = cur -> next -> next; pre -> next -> next = temp; /* Move pre back to new_head. */ pre = new_head; } else cur = cur -> next; } struct ListNode* res = new_head -> next; free(new_head); return res; }
- 和上面那种差不多,先比较连续的两个值,如果后面的值比前面的值大,则后面的值就要开始逐一与前面的链表里的值比较,插入进去
- 关键点就是保证new_head的头结点不变,每次都从这个头结点开始查询,插入
- 上面的方法是对于每一个新的值都要与之前的所有值比较,这个方法是,先和连续的前一个值比较,如果已经比上一个值打了就不需要重新全部比较