首页 > 其他分享 >归并排序

归并排序

时间:2024-04-23 17:22:49浏览次数:26  
标签:sort 归并 int mid merge 数组 排序 my

归并排序是一种基于分治的算法,下面给出我的数组式(半数组,有偏移理解)
代码:

点击查看代码
//注意:我的答案数组下标开始为1,且所有操作区间均为闭区间
//时间复杂度:稳定o(nlogn)
//空间复杂度:o(n),栈空间:o(nlogn),若开全局数组则可忽略栈空间
#include <bits/stdc++.h>
using namespace std;
void my_merge(int a[],int s1,int b[],int s2,int temp[])//合并两个有序数组(其实是有序队列)
{
	//有点像01背包第k优解的感觉
    int k = 0,i = 0,j = 0;//因为这里传入的是首地址,故下标从0开始
    while(i<s1&&j<s2)//直到其中一个队列先空为止
    {
        if(a[i] <= b[j]) temp[k] = a[i++];//小的在前且移动下标
        else temp[k] = b[j++];
        k++;//移动
    }
    //将为空的继续放入临时数组
    for (;i<s1;i++,k++) temp[k] = a[i];
    for (;j<s2;j++,k++) temp[k] = b[j];
}
void merge_sort(int a[],int l,int r)//我的归并排序,指针式
{
    if(r - l<=1)//特殊处理!!!(产生原因为我的操作为闭区间,当区间为2的时候,一直是二,一边长度为2,一边为0)
    {
        if(l>=r) return;//特殊处理
        if(a[r] < a[l]) swap(a[r],a[l]);//处理长度为二的时候
        return;//返回
    }
    int mid = (l+r)>>1;//分割区间
    merge_sort(a,l,mid-1);
    merge_sort(a,mid,r);
    int temp[1024];//临时数组,大小应该是数组的最大大小,n,故空间复杂度(栈空间nlogn)
    my_merge(&a[l],mid-l,&a[mid],r-mid+1,temp);//合并两个数组为一个有序数组
    for (int i = l;i<=r;i++) a[i] = temp[i-l];//赋值
}
int main()
{
    int n;
    cin>>n;
    int a[n+1];
    for (int i = 1;i<=n;i++) cin>>a[i];
    merge_sort(a,1,n);
    for (int i = 1;i<=n;i++) cout<<a[i]<<"\n";
    return 0;
}

下面是后来完善的我的全数组式(无偏移理解)
代码如下:

点击查看代码
//背景:之前自己在众多指针中创造出我的数组式(下标从0开始)的做法,指针与我的数组最大区别就是下标0问题,故之前的应该叫半我的数组式
//注意区别:仅my_merge()变动
#include <bits/stdc++.h>
using namespace std;
int temp[100005];
void my_merge(int a[],int b1,int e1,int b2,int e2)//直接利用下标处理
{
    int i = b1,j = b2,p = 0;
    while(i<=e1&&j<=e2)
    {
        if(a[i]<a[j]) temp[p] = a[i++];
        else temp[p] = a[j++];
        p++;
    }
    for (;i<=e1;i++) temp[p++] = a[i];
    for (;j<=e2;j++) temp[p++] = a[j];
}
void merge_sort(int a[],int l,int r)
{
    if(r-l<=1)
    {
        if(r<=l) return;
        if(a[r] < a[l]) swap(a[r],a[l]);
        return;
    }
    int mid = (l+r)>>1;
    merge_sort(a,l,mid-1);
    merge_sort(a,mid,r);
    my_merge(a,l,mid-1,mid,r);
    for (int i = l;i<=r;i++) a[i] = temp[i-l];
}
int main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    int n;
    cin>>n;
    int a[n+1];
    for (int i = 1;i<=n;i++) cin>>a[i];
    merge_sort(a,1,n);
    for (int i = 1;i<=n;i++) cout<<a[i]<<" ";
    return 0;
}

标签:sort,归并,int,mid,merge,数组,排序,my
From: https://www.cnblogs.com/cuijunjie18/p/18153334

相关文章

  • 快速排序法
    第一种写法:定标杆在起点时间复杂度:平均o(nlogn),最坏o(n^2)代码如下:点击查看代码#include<bits/stdc++.h>usingnamespacestd;voidquick_sort(inta[],intb,inte){if(b>=e)return;inttemp=a[b];inti=b,j=e;while(i<j){......
  • 说说你对选择排序的理解?如何实现?应用场景?
    一、是什么选择排序(Selectionsort)是一种简单直观的排序算法,无论什么数据进去都是 O(n²)的时间复杂度,所以用到它的时候,数据规模越小越好其基本思想是:首先在未排序的数列中找到最小(or最大)元素,然后将其存放到数列的起始位置然后再从剩余未排序的元素中继续寻找最小(or最大)......
  • vis.js滚动和排序
    代码案例<!doctypehtml><html><head><title>Timeline</title><scripttype="text/javascript"src="https://unpkg.com/vis-timeline@latest/standalone/umd/vis-timeline-graph2d.min.js"></script>......
  • 排序3-插入排序
    排序3-插入排序插入排序把排序对象分成已排序和未排序两个部分,每次选取未排序部分的首元素,将它插入已排序部分的合适部分插入排序(正序)//插入排序voidinsertSort(intarr[],intlength){intj;for(inti=1;i<length;i++){//i是无序部分首元素的下标......
  • 常见的排序算法——归并排序
    本文记述了自顶向下归并排序的基本思想和一份参考实现代码,并在说明了算法的性能后用随机数据进行了验证。◆思想使用自顶向下的分治思想进行排序。将待排序元素分为两个待排序子范围,用递归的方式对两个子范围分别排序。然后将排序结果归并起来,即得到整体排序的结果。归并两个已......
  • SQL Server 中将字符串按数字排序
    方法一:使用CAST或CONVERT我们可以使用CAST或CONVERT函数将字符串转换为数字,然后按照数字进行排序。示例如下:SELECT*FROMYourTableORDERBYCAST(YourColumnASINT)方法二:使用TRY_CAST或TRY_CONVERT如果我们不确定字符串中的所有值都可以成功转换为数字,我们可......
  • 排序2-选择排序
    排序2-选择排序每次找到最值的下标,最后交换元素,每次遍历的元素减少.减少了交换元素的次数.性能较冒泡排序更好一点,但时间复杂度仍是$O(n^2)$交换元素//交换voidSwap(int*a,int*b){inttmp=*a;*a=*b;*b=tmp;}打印数组voidPrintArray(......
  • 过滤与排序
    排序与过滤​ 查询所有才需要过滤,排序是按照某个规则排序排序简单使用导入类OrderingFilter在视图类重写filter_backends属性,在列表内填入导入的类重写ordering_fields属性,在列表内填入字段classBookView(ModelViewSet):queryset=Book.objects.all()serial......
  • 排序1-冒泡排序
    排序1-冒泡排序冒泡排序的次数是递减的,第一次确定了最大元素的位置,所以第二次只需要进行n-1次排列,第二次确定了第二大元素的位置,所以第三次只需要进行n-2次排列,以此类推for(inti=0;i<len;i++){//每次遍历的次数是递减的//所以j=len-1-i......
  • 归并排序
    归并排序左部分有序 ---> 右部分有序 --->整体有序查看代码//https://leetcode.cn/problems/sort-an-array/importjava.util.Arrays;classSolution{publicstaticfinalintMAX_N=100001;publicstaticint[]help=newint[MAX_N];publi......