桶排序,打破排序nlogn界限。

桶排序算法介绍,适用于数据范围较小的情况,通过创建多个桶并分配元素实现快速排序。时间复杂度为O(n+m),空间需求较大。实例解析了如何在ISBN码排序中应用桶排序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

桶排序,算法简单,逻辑简单,时间快,空间大!
先看个例题:就明白了
题目:要登记买书的同学,人数小于100,每个人报一个ISBN码,范围在1~1000;去掉重复的,
并将ISBN码从小大排列

1、桶排序,时间复杂的都为O(n+m),占空间大


```cpp
#include <stdio.h>

int main()
{
    int arr[1001] = {0};
    int n = 0;
    int i = 0;
    int t = 0;
    int count = 0;

    printf("请输入要登记买书的人数\n");
    scanf("%d", &n);
    for(i=1; i<=n; i++) //接受数据,并去重
    {
        scanf("%d", &t);
        arr[t] = 1;
    }

    for(i=1; i<=1000; i++)
    {
        if(arr[i] == 1)
        {
            count++;
            printf("%d ", i);
        }
    }
    printf("\n共要买%d本书\n", count);

    return 0;
}

桶排序就是,用题目给的数据范围做空间大小。
比如给的数据大小在0到1000,那么久定义a[1005],时间
复杂度是O(1000+m),m指的是重复数据的个数,可以忽略

来个高级例题

试题G:体前屈大赛 20'
描述
某校的火柴部部长拟定向筋肉部发起一场特别的活动:体前屈大赛

比赛流程是:公布规则->体前屈测试->颁发奖牌

比赛规则:初始参赛人员共有nn人,已知在体前屈测试后会有qq次特殊事件tt发生:

t=1t=1类事件:中途加入一名隐藏选手,已知他的体前屈成绩为kk;
t=2t=2类事件:将所有参赛人员根据体前屈成绩从左到右升序排序,并给从左到右数第kk个选手颁发倒霉奖
注:颁发了倒霉奖牌的选手仅仅是拥有奖牌,奖牌不会影响这位选手原来的性质与作用。

体前屈测试:在体前屈测试中初始参赛人员每人都会有一个体前屈成绩ai。

颁发奖牌:你是一名有一说一的纯路人裁判,颁发奖牌的任务降临到了你的头上

在你每一次颁发奖牌时,都要报出这位倒霉的选手的体前屈成绩!

请你利用你的计算机优势,编写一个程序, 根据已知条件输出每一次颁发奖牌时, 你需要报出的成绩。

输入
第一行输入22个整数n, qn,q;

第二行输入nn个整数a_i(- 1000≤a_i < 1000)a 
i
​	
 (−1000≤a 
i
​	
 <1000)

第3至(q+ 2)3至(q+2)行每行输入22个整数

t, k(1\le t\le 2,\begin{cases} -1000\le k \le 1000,t=1\\ 1\le k\le n, t = 2\end{cases})t,k(1≤t≤2,{ 
−1000≤k≤1000,t=1
1≤k≤n,t=2
​	
 )

能够保证至少有一个t = 2,即不会出现没有输出的情况。

输出
对于每个t = 2输出1个整数

样例
输入复制
5 8
-1000 1000 4 -5 0
2 1
2 2
2 3
2 4
2 5
1 -1000
2 1
2 2
输出复制
-1000
-5
0
4
1000
-1000
-1000
提示
数据规模

对于10\%10%的数据,1 \le n \le 10, 1\le q \le 101≤n≤10,1≤q≤10

对于40\%40%的数据,1 \le n \le 5000, 1\le q \le 2001≤n≤5000,1≤q≤200

对于100\%100%的数据,1 \le n \le 10^6, 1\le q \le 100001≤n≤10 
6
 ,1≤q≤10000

```cpp
#include<iostream>
using namespace std;
int n,q;
int a[2005];
int qu[100000];
int main()
{
	int flag=0;
	cin>>n>>q;
	for(int i=1;i<=n;i++)
	{
		int t;
		cin>>t;
		a[t+1000]++;
	}
	while(q--) 
	{
		int x,y;
		cin>>x>>y;
		if(x==1)
		{
			a[1000+y]++;
		}
		else
		{
			int c=0;
			for(int i=0;i<2005;i++)
			{
				int b=a[i];
				c=c+a[i];
				if(c>=y) 
				{
					cout<<i-1000<<endl;
					break;
				}
			
			}
			
		}
	}
 	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值