基数、二路归并排序

1.基数排序

将所有数据从左向右,依次按照低位优先,全部进入到桶内,再从桶内取出

时间复杂度:O(dn) 空间复杂度:O(dn)

稳定性:稳定

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

void Get_Figure_Max(int *arr,int len)
{
    int max = arr[0];
	for(int i=1; i<len; i++)
	{
		if(arr[i] > max)
		{
			max = arr[i];
		}
	}

    int count=0;
    while(max!=0)
    {
		count++;
        max/=10;
    }
    return count;
}
//获取过去值n的index这个位的值是多少      
int Get_Num(int n,int index)
{
    for(int i=0;i<index;i++)
    {
        n=n/10;
    }
    return n%10;
}
static void Radix(int *arr,int len,inr index)
{
    int brr[10][20];//申请的0~9号桶,每个桶有20个空间
    int crr[10]={0};//用crr[i]的值代表对应i号桶内有多少有效值
    
    for(int i=0;i<len;i++)
    {
        int tmp=Get_Num(arr[i],index);//tmp保存着应该放的桶号
        brr[tmp][crr[tmp]++]=arr[i];
    }
    
    int k=0;
    for(int i-0;i<=9;i++)//桶号
    {
        for(int j=0;j<crr[i];j++)
        {
            arr[k++]=brr[i][j];
        }
    }
}
void Radix_Sort(int *arr,int len)
{
    int count=Get_Figure_Max(arr,len);
    
    for(int i=0;i<len;i++)
    {
       Radix(arr,len,i);//i=0以个位排序一次,i=1以十位排序一次,依次类推
    }
}

2.归并排序

一开始将所有的数据看成单独的个体,接着依次融合,直到所有的数据融合到一组,则停止

时间复杂度:O(nlog2 n) 空间复杂度:O(nlog2 n)

稳定性:稳定

L1<H1 左边组值不止一个(ok)

L1=H1 左边组值仅有一个(ok)

L1>H1 左边组值一个都没用(error)

图20

//根据传进来的gap进行几几合并
static void Merge(int *arr,int len,int gap)
{
    //因为数据本身空间不够用,所以要申请一个和原数组等长的动态内存
    int *brr=(int *)malloc(sizeof(int)*len);
    assert(brr!=NULL);
    
    int L1=0;
    int H1=L1+gap-1;
	int L2=H1+1;
    int H2=(L2+gap-1<len)?(L2+gap-1):(len-1);//防止特殊情况,即数组尾部数据不足,导致越界
    int i=0;//brr的下标
    while(L2<len)//保证左边和右边都抓到了组
    {
        while(L1<=H1&&L2<=H2)//保证左边和右边抓到的组内部还有数据
        {
            if(arr[L1]<=arr[L2])
            {
                brr[i++]=arr[L1++];
            }
            else
            {
                brr[i++]=arr[L2++];
            }
        }
        //判断哪边没漏,则将其剩余数据挪下来
        while(L1<=H1)//如果左边还有数据,挪入brr
        {
            brr[i++]=arr[L1++];
        }
        while(L2<=H2)//如果右边还有数据,挪入brr
        {
            brr[i++]=arr[L2++];
        }
        //右边肯定没抓到(左边抓到,右边没抓到;左右都没抓到)
   	 	L1=H2+1;
    	H1=L1+gap-1;
		L2=H1+1;
    	H2=(L2+gap-1<len)?(L2+gap-1):(len-1);
        //上述变量若是越界,会在while判断中直接退出,不会影响结果
    }
    while(L1<len)//如果左边还有数据,挪入brr
    {
        brr[i++]=arr[L1++];
    }
    //此时调整后的数据都在brr内
    for(int j=0;j<len;j++)
    {
        arr[j]=brr[j];
    }
    free(brr);
}
void MergeSort(int *arr,int len)
{
	for(int i=1;i<len;i*=2)//i代表几几合并的几
    {
    	Merge(arr,len,i);//O(n)    
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值