各种List Sort

排序算法,扩展到List上面,除了需要随机访问,均可以实现。如 归并排序,插入排序,选择排序,快排等。下面依依列出几个。

Insertion Sort List

Sort a linked list using insertion sort.

题目:实现链表的插入排序。

分析:插入排序比较简单,假定一个节点有序的,后面的节点在前面的有序列中找到合适的位置插入。

代码:思想比较简单,关键是思路清楚,定义几个变量保存之后或之前的指针。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *insertionSortList(ListNode *head) {
        if(head==NULL || head->next==NULL) return head;
        ListNode *hhead=new ListNode(INT_MIN);//定义头指针,对于插入到最前边的元素有用
        hhead->next=head;
        ListNode *cur=head->next;
        ListNode *oredered_last=head;//有序序列的最后一个元素,一定是cur的pre元素,用于删除当前的元素,连接链表。
        while(cur){
            if(cur->val >= oredered_last->val){//4 5 6 1 2,扫描到6,直接后移,如果是排好序的
                oredered_last=cur;
                cur=cur->next;
            }else{
                ListNode *t=cur;
                cur=cur->next;
                ListNode *ph=hhead;
                while((ph->next->val <= t->val) && ph->next!=cur){//从前往后找可以 可以插入的位置
                    ph=ph->next;
                }
                oredered_last->next=cur;//del t
                t->next=ph->next;
                ph->next=t;
                
            }
            
        }//cur
        return hhead->next;
    }
};


Sort List

Sort a linked list in O(n log n) time using constant space complexity.

题目:链表排序,要求时间复杂度 O(n log n)。

分析:归并排序,快排时间复杂度最坏的情况下是O(n^2)

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *sortList(ListNode *head) {//归并排序
        if(head==NULL || head->next==NULL) return head;
        ListNode *slow=head;
        ListNode *fast=head->next;
        while(fast && fast->next){
            slow=slow->next;
            fast=fast->next->next;
        }
        fast=slow->next;
        slow->next=NULL;//快慢指针,将链表分成两段
        ListNode *m1=sortList(head);
        ListNode *m2=sortList(fast);
        return merge(m1,m2);
    }
    
    ListNode* merge(ListNode *m1, ListNode *m2){
        if(m1==NULL) return m2;
        if(m2==NULL) return m1;
        ListNode *l1=m1;
        ListNode *l2=m2;
        ListNode *p=NULL;
        ListNode *retres;
        while(true){
            if(l1 && l2){
                if(l1->val <= l2->val){
                    if(p==NULL){
                        p=l1; retres=p;
                    }else{
                        p->next=l1; p=p->next;
                    }
                    l1=l1->next;
                }else{
                    if(p==NULL){
                        p=l2; retres=p;
                    }else{
                        p->next=l2; p=p->next;
                    }
                    l2=l2->next;
                }
            }else if(l1){//l1不空 l2空
                p->next=l1;
                break;
            }else if(l2){
                p->next=l2;
                break;
            }else{
                break;
            }
        }//while
        return retres;
    }
  
};

Partition List

Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.

You should preserve the original relative order of the nodes in each of the two partitions.

For example,
Given 1->4->3->2->5->2 and x = 3,
return 1->2->2->4->3->5.

题目:将链表以x为大小中心,分成两部分。

分析:从前往后扫描,大于x的 不动,小于x,插入到小于x序列末尾。快排的部分。

代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *partition(ListNode *head, int x) {
        if(head==NULL || head->next==NULL) return head;
        ListNode *hhead=new ListNode(INT_MIN);//头指针
        hhead->next=head;
        ListNode *pre=hhead;//小于x的序列的末尾
        ListNode *beforecur=hhead;//cur的前一个值
        ListNode *cur=head;
        while(cur && cur->val < x ){//找到第一个大于x的值
            cur=cur->next;
            pre=pre->next;
            beforecur=beforecur->next;
        }
        while(cur){
            if(cur->val >= x) {
                beforecur=beforecur->next;
                cur=cur->next;
            }else{
                ListNode *t=cur;
                cur=cur->next;
                //delete t
                beforecur->next=cur;
                //insert t到小于x的序列中
                t->next=pre->next;
                pre->next=t;
                pre=t;
            }
        }
        return hhead->next;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值