直接插入排序与基数排序(算法与数据结构)

目录

一、直接插入排序

二、基数排序(桶排序)


一、直接插入排序

直接插入排序的基本思想是每次从待排序列中找到最小值,与第一个值进行交换

时间复杂度O(n^2)空间复杂度O(1)稳定性:稳定

所以我们根据这个思想那么代码就很容易实现了:

void Select_Sort(int *arr,int len) {
	for (int i = 0; i < len-1;i++) {
		for (int j = i+1 ; j < len;j++) {
			if (arr[i]>arr[j]) {
				int tmp = arr[i];
				arr[i] = arr[j];
				arr[j] = tmp;
			}
		}
	}
}
void show(int *arr,int len) {
	for (int i = 0; i < len ;i++) {
		printf("%3d",arr[i]);
	}
}
int main() {
	int arr[] = {1,5,3,4,8,6,7,5,4};
	int len = sizeof(arr) / sizeof(arr[0]);
	Select_Sort(arr,len);
	show(arr,len);
}

测试用例:

二、基数排序(桶排序)

桶排序的基本思想是,申请10个队列,分别来表示0-9

例如

 

在这里我们要注意,第一次排序之后,这些数据的个位数已经有序了

 

第二次排序之后,这些数据的十位和个位都已经有序了。 

 

 

 第三次排序之后,这些数据已经全部有序

既然了解了大体思路,那我们就开始编写代码吧

首先,要获取这些数据中最大数据的位数

int Get_Max_Num(int *arr,int len) {//获取最大值位数
	int tmp = arr[0];
	for (int i = 0; i < len - 1;i++) {//将数组遍历一遍,找到这些数据中的最大值
		if (arr[i] > tmp) {
			tmp = arr[i]; 
		}
	}
	int count = 0;
	while (tmp!=0) {//求最大数据的位数
		tmp /= 10;
		count++;
	}
	return count;
}
int Get_Num_finger(int n,int fin) {//求数据每一  位的数据例如  123 百位是1 十位是2 个位是3
	for (int i = 0; i < fin;i++) {
		n /= 10;
	}
	return n%10;
}
void Radix(int *arr,int len,int fin) {
	queue<int> bucket[10];//定义队列
	for (int i = 0; i < len;i++) {
		int index = Get_Num_finger(arr[i], fin);
		bucket[index].push(arr[i]);//将对应的数据位数放入对应的队列(入队)
	}
	int k = 0;//k代表桶内数据重新向arr写入时,开始的下标
	for (int i = 0; i <= 9;i++) {
		while (!bucket[i].empty()) {//当队列不空时
			arr[k++] = bucket[i].front();//获取队头元素值
			bucket[i].pop();//出队
		}
	}
}
void Radix_Sort(int *arr,int len) {
	int finger = Get_Max_Num(arr,len);//接收数据的最大位数
	for (int i = 0; i < finger;i++) {//求每一  位数的值准备放入队(C++内部函数)中
		Radix(arr,len,i);
	}
}
void show(int *arr,int len) {//打印函数,不必多说了>-<
	for (int i = 0; i < len ;i++) {
		printf("%3d",arr[i]);
	}
}
int main() {
	int arr[] = {1,5,3,4,8,6,7,5,4};
	int len = sizeof(arr) / sizeof(arr[0]);
	Radix_Sort(arr,len);
	show(arr,len);
}

测试用例:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值