LeetCode: Insertion Sort List(外加对单链表类题目的思考总结)

本文分享了链表类题目的解决技巧,包括通过建立伪头节点简化算法处理过程、利用双指针快速定位链表中点及在链表排序过程中采用指针重指向代替复制与交换等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用直接插入排序。值得考虑的是,是否可以使用二分搜索的插入排序?希望有实现了的朋友告诉我。

几道链表类题目做下来,总结出两个技巧:

1.对没有头结点的链表,首先建立伪头结点dummy,这样一来,当算法需要始终维护一个当前指针的父结点指针pre时,就不至于因为在初始时将父结点pre置为NULL而出错。

2.一步两步方法,可以较快的找到链表的近似中间点的指针;如果使用先遍历整个链表确定长度,在遍历半个链表长度找到中间点的方法,时间复杂度为O(1.5N),而如果同时使用两个指针p1和p2,p1每次移动一步而p2每次移动2步,当p2达到尾部时p1大约位于链表中间点附近,这样做时间复杂度为O(N);代码示意:

ListNode* p1 = head;
ListNode* p2 = head;
while (p2!=NULL && p2->next!=NULL) {
    p1 = p1->next;
    p2 = p2->next->next;
}

 

3.一个算法如果对于顺序表需要进行复制,交换等操作的话,那么当该算法移植到链表上用时,尽可能将复制替换等操作改为连标间的指针重指向操作,尽可能不制造新的链表结点。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
    ListNode *directInsert(ListNode* head) {
        if (head == NULL || head->next==NULL) return head;
        ListNode* dump = new ListNode(0);
        dump->next = head;
        ListNode* p = head->next;
        ListNode* p_pre = head;
        ListNode* p_next = p->next;
        int temp;
        int mark = 0;
        while (p != NULL) {
            mark = 0;
            p_next = p->next; //必须在交换发生前确定好下一个待插入元素的指针
            temp = p->val;
            ListNode* q = dump->next;
            ListNode* q_pre = dump;
            while (q != p) {
                if (q->val > temp) {
                    p_pre->next = p->next; //p父结点指向p的子结点
                    p->next = q; //p指向q
                    q_pre->next = p; //q的父结点指向p
                    mark = 1;
                    break; //已找到插入位置并插入完毕,结束当前循环
                }
                q_pre = q;
                q = q->next;
            }
            if (mark == 0) p_pre = p_pre->next; //如果没有发生交换,则p_pre后移
            p = p_next;
        }
        head = dump->next;
        delete dump;
        return head;
    }
    
public:
    ListNode *insertionSortList(ListNode *head) {
        return directInsert(head);

    }
};

 

转载于:https://www.cnblogs.com/zanghu/p/3619141.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值