桶排序是另外一种以O(n)或者接近O(n)的复杂度排序的算法. 它假设输入的待排序元素是等可能的落在等间隔的值区间内.一个长度为N的数组使用桶排序, 需要长度为N的辅助数组. 等间隔的区间称为桶, 每个桶内落在该区间的元素. 桶排序是基数排序的一种归纳结果
算法的主要思想: 待排序数组A[1...n]内的元素是随机分布在[0,1)区间内的的浮点数.辅助排序数组B[0....n-1]的每一个元素都连接一个链表.将A内每个元素乘以N(数组规模)取底,并以此为索引插入(插入排序)数组B的对应位置的连表中. 最后将所有的链表依次连接起来就是排序结果.
这个过程可以简单的分步如下:
- 设置一个定量的数组当作空桶子。
- 寻访序列,并且把项目一个一个放到对应的桶子去。
- 对每个不是空的桶子进行排序。
- 从不是空的桶子里把项目再放回原来的序列中。
note: 待排序元素越均匀, 桶排序的效率越高. 均匀意味着每个桶在中间过程中容纳的元素个数都差不多,不会出现特别少或者特别多的情况, 这样在排序子程序进行桶内排序的过程中会达到最优效率.
note: 将元素通过恰当的映射关系将元素尽量等数量的分到各个桶(值区间)里面, 这个映射关系就是桶排序算法的关键.桶的标记(数组索引Index)的大小也要和值区间有对应关系
下面是一段来自互联网的算法引用, 桶排序算法的C++实现, 非作者原创!
1: #
2: #include <iostream>
3: #
4: #include <ctime>
5: #
6: #include <cmath>
7: #
8: using namespace std;
9: #
10: void main()
11: #
12:
13: #
14: {
15: #
16:
17: #
18: long choice;
19: #
20: long start,end;
21: #
22: MUNE: cout<<"桶排序:1.正常情况 2.最坏情况 3.退出"<<endl;
23: #
24: cin>>choice;
25: #
26:
27: #
28:
29: #
30: struct node //定义链表
31: #
32: {
33: #
34: double item;
35: #
36: node *next;
37: #
38: node(double x,node *n)
39: #
40: {
41: #
42: item=x;
43: #
44: next=n;
45: #
46: }
47: #
48: };
49: #
50: typedef node *link; //构造链表
51: #
52: const long ARRAYNUM=10000; //定义要求要求排序数组大小
53: #
54: const long BUCKETNUM=10000; //定义桶的数量
55: #
56: double *SortArray;
57: #
58: SortArray=new double[ARRAYNUM];//定义排序数组
59: #
60: link *Bucket;
61: #
62: Bucket=new link[BUCKETNUM]; //定义桶
63: #
64: link t=new node(0,NULL);
65: #
66: link newlink;
67: #
68: link templink=new node(0,NULL);
69: #
70: for (long x=0;x<BUCKETNUM;x++) //初始化桶
71: #
72: {
73: #
74: Bucket[x]=new node(0,NULL);
75: #
76: }
77: #
78:
79: #
80:
81: #
82: srand((unsigned) time(NULL)); //产生随机数组
83: #
84: for (long i=0;i<ARRAYNUM;i++)
85: #
86: {
87: #
88: SortArray[i]=(double)rand()/RAND_MAX;
89: #
90:
91: #
92: }
93: #
94:
95: #
96: start=clock(); //设置时钟起点
97: #
98: for(long j=0;j<ARRAYNUM;j++)
99: #
100: {
101: #
102: newlink=new node(SortArray[j],NULL);
103: #
104: switch(choice) //输入选择
105: #
106: {
107: #
108: case 1: t=Bucket[(long)(BUCKETNUM*SortArray[j])];break;
109: #
110: case 2: t=Bucket[0];break; //最坏情况,数据都在一个桶里
111: #
112: case 3: goto EXIT;break;
113: #
114: }
115: #
116: if(t->item==0) //如果桶为空,则把数据直接放入桶内
117: #
118: {
119: #
120: t->item=SortArray[j];
121: #
122: }
123: #
124: else
125: #
126:
127: #
128: {
129: #
130: if(t->item>SortArray[j]) //桶不为空,待插入数据比原桶内第一个数据小情况
131: #
132: //即数据要插在第一个数据前面
133: #
134: {
135: #
136: templink=t; //前向指针,随着t的编译,templing->next=t
137: #
138: Bucket[(long)(BUCKETNUM*(newlink->item))]=newlink;
139: #
140: newlink->next=templink;
141: #
142: templink=NULL;
143: #
144: }
145: #
146: else
147: #
148: {
149: #
150: while(t!=NULL) //桶不为空,待插入数据比原桶内数据小情况
151: #
152: {
153: #
154: if(t->item<=SortArray[j]) //桶不为空,待插入数据比原桶内第二个及以后数据大情况,
155: #
156: {
157: #
158: templink=t;
159: #
160: t=t->next; //待插入数比桶内数大,链表后向遍历
161: #
162:
163: #
164: if(t==NULL) //链表编译到原桶内最后一个数
165: #
166: {
167: #
168: templink->next=newlink;//将待插数据接在原链表最后
169: #
170: }
171: #
172: }
173: #
174: else //链表比当前数据小,插入数据
175: #
176: {
177: #
178:
179: #
180: newlink->next=t;
181: #
182: templink->next=newlink;
183: #
184: t=NULL;
185: #
186: }
187: #
188:
189: #
190:
191: #
192: }
193: #
194: }
195: #
196: }
197: #
198:
199: #
200:
201: #
202: }
203: #
204: end=clock(); //设置时钟终点
205: #
206: cout<<"所用时间为:"<<end-start<<endl;
207: #
208:
209: #
210: goto MUNE;
211: #
212:
213: #
214: EXIT:;
215: #
216: }
作者:Jeffrey Sun
出处:http://sun.cnblogs.com/
本文以“现状”提供且没有任何担保,同时也没有授予任何权利。本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://sun.cnblogs.com/
本文以“现状”提供且没有任何担保,同时也没有授予任何权利。本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
No comments:
Post a Comment