力扣--对链表进行插入排序--147

该题是不带哨兵位的!!! 

目录

该题是不带哨兵位的!!! 

首先先进行带哨兵位的代码展示:

但是就提论题,力扣上的这道题,没有明确说明附带哨兵位,我们一律按照无哨兵位

 那么针对于这道题,我们需要用不带哨兵位的方法来写:

不带哨兵位:(也是于本题符合的写法)

其方法便是:自己制造哨兵位,然后再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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值