排序算法汇总

排序算法汇总

快速排序

void quickSort(vector<int>& arr, int l, int r) {
        // 子数组长度为 1 时终止递归
        if (l >= r) return;
        // 哨兵划分操作(以 arr[l] 作为基准数)
        int i = l, j = r;
        while (i < j) {
        	// 必须先从右边算起 若先从左边算起,最后的i对应的值是大于哨兵的
            while (i < j && arr[j] >= arr[l]) j--;
            while (i < j && arr[i] <= arr[l]) i++;
            swap(arr[i], arr[j]);
        }
        swap(arr[i], arr[l]);
        // 递归左(右)子数组执行哨兵划分
        quickSort(arr, l, i - 1);
        quickSort(arr, i + 1, r);
    }
};

在这里插入图片描述
快速排序详解

归并排序

void mergesort(vector<int>& arr, vector<int> tmp, int start, int end)
{
    if (start >= end)
    {
        return;
    }

    int mid = (start + end) >> 1;
    mergesort(arr, tmp, start, mid);
    mergesort(arr, tmp, mid + 1, end);
    int pos = start;
    int left = start, right = mid + 1;
    while (left <= mid && right <= end)
    {
        tmp[pos++] = arr[left] <= arr[right] ? arr[left++] : arr[right++];
    }
    while (left <= mid)
    {
        tmp[pos++] = arr[left++];
    }

    while (right <= end)
    {
        tmp[pos++] = arr[right++];
    }
    for (int i = start; i <= end; i++)
    {
        arr[i] = tmp[i];
    }
}

int main()
{
    vector<int> arr = { 3,7,0,1,5 }, tmp(arr.size());
    //showvector(arr);
    mergesort(arr, tmp, 0, arr.size() - 1);
    //showvector(arr);
    return 0;

在这里插入图片描述
归并排序详解

归并排序(链表)

ListNode* sortList(ListNode* head) {
    //自底向上的归并排序 空间复杂度O(1)
    if(!head) return head;
    int length = 0;
    ListNode *node = head;
    while(node)
    {
        length++;
        node = node->next;
    }

    ListNode *dummyhead = new ListNode(0,head);
    for(int sublength = 1; sublength < length; sublength <<= 1)
    {
        ListNode *prev = dummyhead, *cur = dummyhead->next;
        while(cur)
        {
            ListNode *head1 = cur;
            for(int i = 1; i < sublength && cur->next; i++)
            {
                cur = cur->next;
            }
            //剪切出需要排序的两个有序链表
            ListNode *head2 = cur->next;
            cur->next = nullptr;

            //剪切出下一次循环的起始点
            cur = head2;
            for(int i = 1; i<sublength && cur && cur->next; i++)
            {
                cur = cur->next;
            }
            ListNode *next = nullptr;
            if(cur)
            {
                next = cur->next;
                cur->next = nullptr;
            }
            cur = next;

            //将两个有序链表合并并且放入已经排序好的链表中
            ListNode *merged = merge(head1, head2);
            prev->next = merged;
            while(prev->next)
            {
                prev = prev->next;
            }

        }
        
    }
    return dummyhead->next;
}

ListNode *merge(ListNode *headA, ListNode *headB)
{
    ListNode *dummyhead = new ListNode(0);
    ListNode *cur = dummyhead, *p1 = headA, *p2 = headB;
    while(p1 && p2)
    {
        if(p1->val <= p2->val)
        {
            cur->next = p1;
            p1 = p1->next;
        }
        else
        {
            cur->next = p2;
            p2 = p2->next;
        }
        cur = cur->next;
    }
    cur->next = p1 ? p1 : p2;
    return dummyhead->next;
}
//自顶向下 空间复杂度O(logn)
class Solution {
public:
    ListNode* sortList(ListNode* head) {
        return sortList(head, nullptr);
    }

    ListNode* sortList(ListNode* head, ListNode* tail) {
        if (head == nullptr) {
            return head;
        }
        if (head->next == tail) {
            head->next = nullptr;
            return head;
        }
        ListNode* slow = head, *fast = head;
        while (fast != tail) {
            slow = slow->next;
            fast = fast->next;
            if (fast != tail) {
                fast = fast->next;
            }
        }
        ListNode* mid = slow;
        return merge(sortList(head, mid), sortList(mid, tail));
    }

    ListNode* merge(ListNode* head1, ListNode* head2) {
        ListNode* dummyHead = new ListNode(0);
        ListNode* temp = dummyHead, *temp1 = head1, *temp2 = head2;
        while (temp1 != nullptr && temp2 != nullptr) {
            if (temp1->val <= temp2->val) {
                temp->next = temp1;
                temp1 = temp1->next;
            } else {
                temp->next = temp2;
                temp2 = temp2->next;
            }
            temp = temp->next;
        }
        if (temp1 != nullptr) {
            temp->next = temp1;
        } else if (temp2 != nullptr) {
            temp->next = temp2;
        }
        return dummyHead->next;
    }
};

排序链表详解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值