leetcode148归并排序 (递归与非递归c++实现)

14 篇文章 0 订阅
4 篇文章 0 订阅

归并排序:
是一种非线性时间比较类排序,采用分治的策略,通过比较来决定元素间的相对次序.时间复杂度不受数据本身影响.时间复杂度为O(nlogn),空间复杂度为O(n).

算法描述:
1.把长度为n的输入序列分成两个长度为n/2的子序列
2.对这两个子序列分别采用归并排序
3.将两个排好序的子序列合并为一个最终的排序序列.

c++递归实现:

#include<cstdlib>

using namespace std;

void MergeSort(int* A, int* L, int lenOfL, int* R, int lenOfR)
{
        int i=0, j=0, k=0;
        while(i<lenOfL && j<lenOfR)
        {
                if(L[i]<R[j])
                        A[k++]=L[i++];
                else
                        A[k++]=R[j++];

        }
        while(i<lenOfL)
                A[k++]=L[i++];
        while(j<lenOfR)
                A[k++]=R[j++];
}
void Merge(int *A, int len)
{
        if(len<2)
                return;
        int mid= len/2;
        int *L = new int [mid];
        int *R = new int [len-mid];
        for(int i=0; i<mid; i++)
                L[i] = A[i];
        for(int i=mid; i<len ;i++)
                R[i-mid] = A[i];
        Merge(L, mid);
        Merge(R, len-mid);
        MergeSort(A, L ,mid, R, len-mid);
        delete []L;
        delete []R;
}
int main()
{
        int number[8]={1, 4, 6,8, 3,4, 5,1};
        int len = sizeof(number)/sizeof(number[0]);
        Merge(number, len);
        for(int i=0; i<len; i++)
                cout<<number[i]<<" ";
        return 0;

}

非递归实现:

#include <iostream>
#include <cstdlib>
using namespace std;
void mergeSort(int *A, int low, int mid, int high)
{
        int *temp = new int[high-low+1];
        int i=low,j=mid+1,k=0;
        while(i<=mid && j<=high)
        {
                if(A[i]<A[j])
                        temp[k++] = A[i++];
                else
                        temp[k++] = A[j++];
        }
        while(i<=mid)
        {
                temp[k++]=A[i++];
        }
        while(j<=high)
        {
                temp[k++]=A[j++];
        }
        for(int i=low, k=0; i<=high; i++,k++)
                A[i]=temp[k];
        delete []temp;
}
void Merge(int *A, int n)
{
        int size=1,low,high,mid;
        while(size<=n-1)
        {
                low=0;
                while(low+size<=n-1)
                {
                        mid = low+size-1;
                        high = mid+size;
                        if(high>n-1)
                                high = n-1;
                        mergeSort(A,low,mid,high);
                        low = high+1;
                }
                size*=2;
        }
}
int main()
{
        int number[8]={1, 4, 6,8, 3,4, 5,1};
        int len = sizeof(number)/sizeof(number[0]);
        Merge(number, len);
        for(int i=0; i<len; i++)
                cout<<number[i]<<" ";
        return 0;

}

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

Example 1:

Input: 4->2->1->3
Output: 1->2->3->4
Example 2:

Input: -1->5->3->4->0
Output: -1->0->3->4->5

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    //归并排序:时间复杂度O(nlogn),空间复杂度O(n)
    ListNode* sortList(ListNode* head) {
        if(head==nullptr)
            return nullptr;
        if(head->next == nullptr)
            return head;
        ListNode* slow = head;
        ListNode* fast =head;
        while(fast->next && fast->next->next)
        {
            slow = slow->next;
            fast = fast->next->next;;
        }
        ListNode* right = slow->next;
        slow->next = nullptr;
        ListNode* l1 = sortList(head);
        ListNode* l2 = sortList(right);
        return merge(l1, l2);
        
    }
    ListNode* merge(ListNode* left, ListNode* right)
    {
        ListNode* newHead = new ListNode(0), *cur = newHead;
        if(!left) return right;
        if(!right) return left;
        while(left && right)
        {
            if(left->val < right->val)
            {
                cur->next = left;
                left = left->next;
            }
            else
            {
                cur->next = right;
                right=right->next;
            }
            cur = cur->next;
                
        }
        if(left)
            cur->next = left;
        if(right)
            cur->next = right;
        return newHead->next;
    }
};
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值