算法理解:
桶排序是对计数排序的一种优化,在计数排序中x应该放在计数数组下表为x的位置上,这样如果重复数字较少,计数数组每个位置的利用率就非常小。
桶排序是将一系列大小近似的数字放在一个位置(每个桶维护一条有序的链表),这样提高每个位置的利用率,以提高效率.
以A【】={1,21,23,41,49}为例
假设每个桶里有10中元素,那么桶排序的结构如下图所示。
#include <algorithm> #include <iostream> #include <cstring> #include <vector> #include <cstdio> #include <cmath> #include <queue> using namespace std; const int maxn=1e5+10; typedef struct node{ int key; struct node* next; }KeyNode; void bucket_sort(int keys[],int size,int bucket_size){ KeyNode **bucket_table=(KeyNode**)malloc(bucket_size*sizeof(KeyNode*)); for(int i=0;i<bucket_size;i++){ //初始化桶 bucket_table[i]=(KeyNode*)malloc(sizeof(KeyNode)); bucket_table[i]->key=0; bucket_table[i]->next=NULL; } for(int i=0;i<size;i++){ KeyNode* node=(KeyNode*)malloc(sizeof(KeyNode)); node->key=keys[i]; node->next=NULL; int index=keys[i]/10;//给数据分类的方法(关系到排序速度,很重要) KeyNode *p=bucket_table[index]; if(p->key==0){ p->next=node; p->key++; } else{ while(p->next!=NULL&&p->next->key<=node->key){//=的时候后来的元素会排在后面 p=p->next; } node->next=p->next; p->next=node; (bucket_table[index]->key)++; } } KeyNode* k=NULL; for(int i=0;i<bucket_size;i++){ for(k=bucket_table[i]->next;k!=NULL;k=k->next){ printf("%d ",k->key); } } } int main(){ int n;int a[maxn]; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&a[i]); } bucket_sort(a,n,100); return 0; }
例一:
给你一个数组,找到差值绝对值最小是多少?
解:最简单的思路就是先排序,之后遍历一遍,时间复杂度是O(nlogn),那么能否O(n)求解呢,是可以的。
如果有n个数,那么我们把最大到最小值之间的数字分到n-1个桶里,必然会有两个数字在一个桶里(鸽巢原理)(抽屉原理),最小值值可能是这个桶的最小值和上一个桶的最大值的差,或者两个在同个桶的数字,对于不同的桶我们遍历一遍,对于相同的桶又回到了最初的问题,即给你一个数组,找到差值绝对值最小是多少?,这样相同的桶就递归处理,即可使效率达到比较高的状态。
原文地址:https://www.cnblogs.com/wz-archer/p/11689628.html
时间: 2024-10-31 16:23:04