该题是不带哨兵位的!!!
目录
该题是不带哨兵位的!!!
首先先进行带哨兵位的代码展示:
但是就提论题,力扣上的这道题,没有明确说明附带哨兵位,我们一律按照无哨兵位
那么针对于这道题,我们需要用不带哨兵位的方法来写:
不带哨兵位:(也是于本题符合的写法)
其方法便是:自己制造哨兵位,然后再free,返回
针对这题,通过代码:
该题链接
147. 对链表进行插入排序 - 力扣(LeetCode)
我看了不少题解,有的是带哨兵位的来写,有的是不带哨兵位的来写,在这一篇文章中,两者都会进行介绍:
首先先展示c语言简单实现数组的插入排序:
void insertion_sort(int arr[], int len){
int i,j,key;
for (i=1;i<len;i++){
key = arr[i];
j=i-1;
while((j>=0) && (arr[j]>key)) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = key;
}
}
首先先进行带哨兵位的代码展示:
其实现方法就是将数组部分改为对应的链表
struct ListNode* insertionSortList(struct ListNode* head) {
if (head == NULL || head->next == NULL) {
return head; // 处理链表为空或只有一个节点的情况
}
struct ListNode* cur = head->next->next, * ptr = head->next;
struct ListNode* tmp = head;
struct ListNode* cur_prev = head;
int k = 0;
while (cur)
{
//ptr为cur前一个
k = cur->val;
cur_prev = head;
while (cur_prev->next != cur)
{
cur_prev = cur_prev->next;
}
ptr = cur_prev;
if (cur->val >= ptr->val)
{
ptr = ptr->next;
cur = cur->next;
}
else
{
while ((k < ptr->val) && (ptr != head))
{
ptr->next->val = ptr->val;//arr[j+1] = arr[j];
//j--
//存放ptr前一个
tmp = head;
while (tmp->next != ptr)
{
tmp = tmp->next;
}
ptr = tmp;//--完成
ptr->next->val = k;
}
cur = cur->next;
}
}
return head;
}
但是就提论题,力扣上的这道题,没有明确说明附带哨兵位,我们一律按照无哨兵位
所以这样写是不行的,但反过来,该题的测试用例也不能完全通过, 他会有一个这样的测试用例
那么针对于这道题,我们需要用不带哨兵位的方法来写:
不带哨兵位:(也是于本题符合的写法)
我一开始也是完全仿照c语言数组实现插入排序的方法来的
其代码如下:
其方法便是:自己制造哨兵位,然后再free,返回
struct ListNode* insertionSortList(struct ListNode* head) {
if (head == NULL || head->next == NULL) {
return head; // 处理链表为空或只有一个节点的情况
}
struct ListNode* dummy = (struct ListNode*)malloc(sizeof(struct ListNode));
dummy->next = head;
struct ListNode* cur = dummy->next->next, * ptr = head;
// struct ListNode* cur = head->next->next, * ptr = head->next;
struct ListNode* tmp = head;
struct ListNode* cur_prev = head;
int k = 0;
while (cur)
{
//ptr为cur前一个
k = cur->val;
cur_prev = head;
while (cur_prev->next != cur)
{
cur_prev = cur_prev->next;
}
ptr = cur_prev;
if (cur->val >= ptr->val)
{
ptr = ptr->next;
cur = cur->next;
}
else
{
while ((k < ptr->val) && (ptr != dummy))
{
ptr->next->val = ptr->val;//arr[j+1] = arr[j];
//j--
//存放ptr前一个
tmp = dummy;
while (tmp->next != ptr)
{
tmp = tmp->next;
}
ptr = tmp;//--完成
ptr->next->val = k;
}
cur = cur->next;
}
}
free(dummy);
return head;
}
再力扣上运行,可想而知,肯定是不行的,会有一个超出时间限制,有一个测试用例不通过;
那么就需要转换方法:
代码如下:
针对这题,通过代码:
struct ListNode* insertionSortList(struct ListNode* head) {
if (head == NULL || head->next == NULL) {
return head;
}
struct ListNode* sortedHead = head, * sortedTail = head;//尾
head = head->next;
//最后一个
sortedTail->next = NULL;
while (head) {
struct ListNode* cur = head;
// 移动head指针到下一个节点
head = head->next;
//给sortedHead换头,直到合适
if (cur->val <= sortedHead->val)//头插,更换头
{
cur->next = sortedHead;
sortedHead = cur;
}
//sorthead的next没改
//不是头查
//弹药挨个比较找到对应的位置
else
{
struct ListNode* tmp = sortedHead;
//找到了对应位置
while ((tmp != sortedTail) && (tmp->next->val <= cur->val))
{
tmp = tmp->next;
}
cur->next = tmp->next;//等价于 sortedTail->next=NULL;
tmp->next = cur;
//但如果对应位置为尾节点
//更新Tail
if (tmp == sortedTail)
{
sortedTail = cur;
//此时的tmp为最后一个的下一个 NULL
}
}
}
return sortedHead;
}