桶排序

桶排序是一种扩展的计数排序方法,通过映射函数将元素分配到不同桶中,每个桶内部排序后,再依次放回原数组。关键在于元素的均匀分布,以保证效率。文中介绍了算法步骤,包括找最大最小值、创建桶、元素入桶、桶内排序以及合并。个人体会提到桶排序可结合冒泡排序等方法实现。

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

算法过程:
1.找到Max,Min
2.拆高位
3.申请桶
4.元素入桶
5.桶排序
6。放回原数组
7.释放

思想
一句话总结:划分多个范围相同的区间,每个自区间自排序,最后合并。

桶排序是计数排序的扩展版本,计数排序可以看成每个桶只存储相同元素,而桶排序每个桶存储一定范围的元素,通过映射函数,将待排序数组中的元素映射到各个对应的桶中,对每个桶中的元素进行排序,最后将非空桶中的元素逐个放入原序列中。

桶排序需要尽量保证元素分散均匀,否则当所有数据集中在同一个桶中时,桶排序失效。

个人体会:
桶排序就是相同位数的排序。主要在于两点,元素入桶和排序两个阶段。元素入桶在于确定下标nIndex,利用头插法将元素入桶。桶排序有多种方式可用,冒泡排序,选择排序,插入排序。运用插入排序时,我们可以在元素入桶的时候就排序。下面代码我用冒泡排序来实现。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct node
{
    int nVal;
	struct node *pNext;
}Bucket;

void Sort(Bucket *pHead)
{
	Bucket *pTemp = NULL;
	Bucket *pMark = pHead;
	while (pHead)
	{
		pTemp = pMark;
		while (pTemp->pNext != NULL)
		{
			if(pTemp->nVal > pTemp->pNext->nVal)
			{
				pTemp->nVal = pTemp->nVal^pTemp->pNext->nVal;
				pTemp->pNext->nVal = pTemp ->nVal^pTemp->pNext->nVal;
				pTemp->nVal = pTemp->nVal^pTemp->pNext->nVal;
			}
			pTemp = pTemp->pNext;
		}
		pHead = pHead->pNext;
	}


}
Bucket **BucketSort(int arr[],int len)
{
	if(arr == NULL || len <= 0)
		return NULL;
	int max = arr[0];
	int min = arr[0];
	int i;
	for(i = 0;i<len;i++)
	{
		if(arr[i] > max)
			max = arr[i];
		if(arr[i] < min)
			min = arr[i];
	}
	int num;
	int count = 1;
	num = max;
	while (num)
	{
		count = count * 10;
		num = num/10;
	}
	count = count /10;

	int maxIndex = max/count;
	int minIndex = min/count;
	//指针数组
	Bucket **pBucket = (Bucket**)malloc(sizeof(Bucket*)*(maxIndex-minIndex+1));
	memset(pBucket,0,sizeof(Bucket*)*(maxIndex-minIndex+1));

	//元素入桶
	int Index;
	Bucket *pTemp =NULL;
	for(i = 0;i<len;i++)
	{
		Index = arr[i]/count-minIndex;
		pTemp = (Bucket*)malloc(sizeof(Bucket));
		pTemp->nVal = arr[i];
        //头插法
		pTemp->pNext = pBucket[Index];
		pBucket[Index] = pTemp;
	}
	//桶排序
	for(int i = 0;i<maxIndex-minIndex+1;i++)
	{
		Sort(pBucket[i]);
	}
	//放回原数组
	num = 0;
	for(i = 0;i<maxIndex-minIndex+1;i++)
	{
		pTemp = pBucket[i];
		while (pTemp)
		{
			arr[num++] = pTemp->nVal;
			pTemp = pTemp->pNext;
		}
	}
	//释放
	Bucket *pDel = NULL;
	for(i = 0;i<maxIndex-minIndex+1;i++)
	{
		pTemp = pBucket[i];
		while (pTemp)
		{
			pDel = pTemp;
			pTemp = pTemp->pNext;
			free(pDel);
			pDel = NULL;
		}
	}
	free(pBucket);
	pBucket = NULL;
}

void Print(int arr[],int nLength)
{
	if(arr == NULL || nLength <= 0)return;

	int i;
	for(i = 0;i<nLength;i++)
	{
		printf("%d ",arr[i]);
	}
	printf("\n");
}

int main()
{
	int arr[] = {106,233,128,659,211,164,763,328,591,209,217,187,101,222};
	BucketSort(arr,sizeof(arr)/sizeof(arr[0]));
	Print(arr,sizeof(arr)/sizeof(arr[0]));
	return 0;
}

1.https://blog.youkuaiyun.com/developer1024/article/details/79770240

2.https://blog.youkuaiyun.com/qq_37186247/article/details/100834916?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值