114-对基数排序算法的实现和分析

基数排序

在此先书写一下需要用到的辅助函数和队列的实现(需要用到队列)

#include<stdlib.h>
#include<string.h>
#define INITSIZE 10
#include<stdio.h> 

typedef int ElemType;

typedef struct queue
{
	ElemType *data;//存储元素的空间的首地址
	int      front;//队列头
	int       rear;//队列尾
	int       size;//标识当前空间的结束位置 扩容 
}Queue;

void InitQueue(Queue *que)//初始化 
{
	if(que==NULL) exit(0);
	que->data=(ElemType *)malloc(sizeof(ElemType)*INITSIZE);
	if(que->data==NULL) exit(0);
	que->front=que->rear=0;
	que->size=INITSIZE; 
}


static bool AppendSpace(Queue *que)//扩容 
{
	ElemType *new_space=(ElemType *)malloc(sizeof(ElemType)*que->size*2);
	if(new_space==NULL) return false;
	int index=0;
	while(que->front!=que->rear)
	{
		new_space[index++]=que->data[que->front];
		que->front=(que->front+1)%que->size; 
	}
	que->front=0;
	que->rear=que->size-1;
	que->size *=2;
	free(que->data);
	que->data=new_space;
	return true;
}

bool IsFull(Queue *que)//判满 
{
	if(que==NULL) exit(0);
	return (que->rear+1)%que->size==que->front;//类似于处理环形 
}

bool IsEmpty(Queue *que)//判空 
{
	if(que==NULL) exit(0);
	return que->front==que->rear;
}

bool Push(Queue *que,ElemType val)//入队(从尾入) 
{
	if(que==NULL) exit(0);
	if(IsFull(que))
	{
		if(!AppendSpace(que))
		{
			return false;
		}
	}
	que->data[que->rear]=val;
	que->rear=(que->rear+1)%que->size;
	return true;
}

bool Top(Queue *que,ElemType *reval)//获取队列头的值 
{
	if(que==NULL) exit(0);
	if(IsEmpty(que)) return false;
	*reval=que->data[que->front];
	return true;
}

bool Pop(Queue *que)//出队(从头出) 
{
	if(que==NULL) exit(0);
	if(IsEmpty(que)) return false;
	que->front=(que->front+1)%que->size;
	return true;
}

void DestroyQueue(Queue *que)//销毁 
{
	if(que==NULL) exit(0);
	free(que->data);
	que->data=NULL;
	que->front=que->rear=que->size=0;
}

/*辅助函数:
    1.打印数据
	2.判断整个数据序列是否已经有序
	3.交互两个数据swap方法
*/

void Show(int *arr,int len)//打印数据
{
	for(int i=0;i<len;++i)
	{
		printf("%d  ",arr[i]);
	}
	printf("\n");
}

bool IsSort(int *arr,int len)//判断整个数据序列是否已经有序
{
	for(int i=0;i<len-1;++i)
	{
		if(arr[i]>arr[i+1])
		{
			return false;
		}
	}
	return true;
}

void SwapValue(int *a,int *b)//交互两个数据swap方法
{
	int tmp=*a;
	*a=*b;
	*b=tmp; 
}

什么是基数排序

基数排序是一个针对于有多个关键字的排序算法
数字模拟有多个关键字:个位 十位 百位 千位 …
按某一位上的数值进行排序:按照这一位上的数字的取值范围(0-9)申请相应个数的队列
遍历整个待排序序列,将每一个数据按照这一位上的数值存储到相应下标的队列中
将队列中的数值按照顺序依次弹出

下图是示例
先从个位 后从十位 按照队列
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
接下来实现基数排序算法

int GetMaxDigits(int *arr,int len)//获取序列中最大值的位数
{
	int max_value=arr[0];
	for(int i=0;i<len;++i)
	{
		if(max_value<arr[i])
		{
			max_value=arr[i];
		}
	}
		int digits=0;
		while(max_value)
		{
			digits++;
			max_value/=10;
		}
		return digits;
}

int GetDigitsValue(int value,int digits)
{
	while(digits)
	{
		value/=10;
		digits--;
	}
	return value%10;
}

void RadixSort(int *arr,int len)
{
	//最长的位数
	int max_digits=GetMaxDigits(arr,len);
	Queue que[10];
	for(int i=0;i<10;++i)
	{
		InitQueue(&que[i]);
	}
	for(int i=0;i<max_digits;++i)
	{
		for(int j=0;j<len;++j)
		{
			int digits_value=GetDigitsValue(arr[j],i);
			Push(&que[digits_value],arr[j]);
		}
		int index=0;
		for(int k=0;k<10;++k)
		{
			while(!IsEmpty(&que[k]))
			{
				Top(&que[k],&arr[index]);
				index++;
				Pop(&que[k]);
			}
		}
	}
	for(int i=0;i<10;++i)
	{
		DestroyQueue(&que[i]);
	} 
}

最后完成主函数

int main()
{
	int arr[]={7,87,29,75,41,50,62,92,69,22,76,77,35};
	Show(arr,sizeof(arr)/sizeof(arr[0]));
	RadixSort(arr,sizeof(arr)/sizeof(arr[0]));
	Show(arr,sizeof(arr)/sizeof(arr[0])); 
	return 0;
	
}

运行结果如下
在这里插入图片描述
基数排序算法的分析
时间复杂度 O(dn) d:关键字的个数
空间复杂度O(w
n) w:数字取值范围的个数
稳定性:稳定

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林林林ZEYU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值