桶排序(BucketSort)
1 桶排序核心思想是 根据数据规模n划分 m个相同大小的区间 (每个区间为一个桶,桶可理解为容器)
2 每个桶存储区间内的元素(区间为半开区间 例如[0,10) 或者 [200,300) )
3 将n个元素按照规定范围分布到各个桶中去
4 对每个桶中的元素进行排序,排序方法可根据需要,选择快速排序,或者归并排序,或者插入排序
5 依次从每个桶中取出元素,按顺序放入到最初的输出序列中(相当于把所有的桶中的元素合并到一起)
6 桶可以通过数据结构链表实现
7 基于一个前提,待排序的n个元素大小介于0~k 之间的整数 或者是(0, 1)的浮点数也可(算法导论8.4的例子)
8 桶排序的时间代价,假设有m个桶,则每个桶的元素为n/m
当辅助函数为冒泡排序O(n2) ,桶排序为 O(n)+mO((n/m)2)
当辅助函数为快速排序时O(nlgn), 桶排序为 O(n)+mO(n/m log(n/m))
9 通常桶越多,执行效率越快,即省时间,但是桶越多,空间消耗就越大,是一种通过空间换时间的方式
注意:代码前部分为辅助代码
辅助类:链表Link
辅助函数:冒泡排序BubbleSort
#include <iostream>
#include <crtdbg.h>
#include <cstring>
using namespace std; typedef int DataType;
//建立链表
class Link
{
private:
struct Node
{
DataType data;
Node *next;
};
Node *head; //哨兵位
public:
Link()
{
Init();
}
~Link()
{
Delete();
}
void Init()
{
head = new Node;
head->next = NULL;
}
void Delete()
{
for (Node *p = head; p != NULL;)
{
Node *pTemp = p->next;
delete p;
p = pTemp;
}
head = NULL;
}
void Print()
{
for (Node *p = head->next; p != NULL; p = p->next)
{
cout << p->data << endl;
}
}
//顺序插入 考虑两种情况 1.空表 2.当插入值是最大值的时候
void SortInsert(DataType data)
{
Node *p = head;
do
{
if (p->next == NULL || p->next->data > data)
{
Node *pNew = new Node;
pNew->data = data;
pNew->next = p->next;
p->next = pNew; return;
}
p = p->next;
} while (true);
}
//尾插法直接插入
void Insert(DataType data)
{
Node *p = head;
while(p->next != NULL)
{
p = p->next;
} Node *pNew = new Node;
pNew->data = data;
pNew->next = NULL;
p->next = pNew;
}
bool Empty()
{
return head->next == NULL;
}
//去掉首结点并返回首结点的值
int ExtractDate()
{
if (! Empty())
{
DataType data = head->next->data;
Node *p = head->next;
Node *pFirst = p->next; delete p;
p = NULL; head->next = pFirst;
return data;
}
return -;
}
};
//冒泡排序
void BubbleSort(int *a, int size)
{
for(int i=; i<size; ++i)
{
for (int j=; j<size--i; ++j)
{
if (a[j] > a[j+])
{
int tmp = a[j];
a[j] = a[j+];
a[j+] = tmp;
}
}
}
}
//基于一个前提:待排序的n个元素大小是介于 0~k 之间的整数
//array待排序数组,result辅助数组存储排序结果,k为允许的最大整数
void BucketSort(int array[], int result[], int size, int k)
{
Link *Bucket = new Link[]; //建立桶
int sectionSize = k/; //记录区间大小
int index=; //记录区间下标 //方法1:一般步骤
//按照范围把array中的每个值放入相应的桶中
for(int i=; i<size; ++i)
{
index = array[i]/sectionSize;
Bucket[index].Insert(array[i]); //为保证稳定性,链表使用了尾插法插入
}
//遍历每个桶,取出桶中的元素,放入辅助数组result,并排序
int j= , m=;
for (int i=; i<; ++i)
{
m = j; //记录已排好序的数组元素大小
while(!Bucket[i].Empty())
{
result[j++] = Bucket[i].ExtractDate();
} //可根据实际情况选择快速排序,堆排序等,此处简单起见选择冒泡排序
BubbleSort(result+m, j-m);
} //方法2:使用链表特性,在插入链表的同时排序
//for(int i=0; i<size; ++i)
//{
// index = array[i]/sectionSize;
// Bucket[index].SortInsert(array[i]);
//}
//int j=0;
//for(int i=0; i<5; ++i)
//{
// while(!Bucket[i].Empty())
// {
// result[j++] = Bucket[i].ExtractDate();
// }
//} delete [] Bucket;
} void main()
{
//检测是否有内存泄露 需要加头文件#include <crtdbg.h>
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); int Array[] = {, , , , , , , , , };
int Result[] = {}; BucketSort(Array, Result, sizeof(Array)/sizeof(Array[]), ); for (int i= ; i < ; ++i)
{
cout << Result[i] << "\n";
} system("pause");
}
(转载请注明作者和出处^_* Seven++ http://www.cnblogs.com/sevenPP/ )
桶排序(BucketSort)的更多相关文章
- Java基础知识强化51:经典排序之桶排序(BucketSort)
1. 首先说明三点: (1)桶排序是稳定的 (2)桶排序是常见排序里最快的一种,比快排还要快…大多数情况下 (3)桶排序非常快,但是同时也非常耗空间,基本上是最耗空间的一种排序算法 2. 桶排序的分析 ...
- 基于非比較的排序:计数排序(countSort),桶排序(bucketSort),基数排序(radixSort)
计数排序 条件:要排序的数组的元素必须是在一定范围的,比方是1~100.在排序之前我们必须知道数组元素的范围. 思路:顾名思义:就是用一个数组来计数的. 步骤: 1.用一个数组来计数count[ ], ...
- BucketSort(桶排序)原理及C++代码实现
桶排序假设输入数据服从均匀分布,平均情况下它的时间复杂度为O(n). 桶排序将输入数据的区间均匀分成若干份,每一份称作“桶”.分别对每一个桶的内容进行排序,再按桶的顺序输出则完成排序. 通常使用链表来 ...
- 计数排序和桶排序(Java实现)
目录 比较和非比较的区别 计数排序 计数排序适用数据范围 过程分析 桶排序 网络流传桶排序算法勘误 桶排序适用数据范围 过程分析 比较和非比较的区别 常见的快速排序.归并排序.堆排序.冒泡排序等属于比 ...
- Java排序算法——桶排序
文字部分为转载:http://hxraid.iteye.com/blog/647759 对N个关键字进行桶排序的时间复杂度分为两个部分: (1) 循环计算每个关键字的桶映射函数,这个时间复杂度是O(N ...
- Hark的数据结构与算法练习之桶排序
算法说明 桶排序的逻辑其实特别好理解,它是一种纯粹的分而治之的排序方法. 举个例子简单说一下大家就知道精髓了. 假如对11,4,2,13,22,24,20 进行排序. 那么,我们将4和2放在一起,将1 ...
- Python线性时间排序——桶排序、基数排序与计数排序
1. 桶排序 1.1 范围为1-M的桶排序 如果有一个数组A,包含N个整数,值从1到M,我们可以得到一种非常快速的排序,桶排序(bucket sort).留置一个数组S,里面含有M个桶,初始化为0.然 ...
- 桶排序与基数排序代码(JAVA)
桶排序 publicstaticvoid bucketSort(int[] a,int max){ int[] buckets; if(a==null || m ...
- Java实现桶排序和基数排序
桶排序代码: import java.util.Arrays; /** * 桶排序 * 工作的原理是将数组分到有限数量的桶里 * 每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序 ...
随机推荐
- matlab inpolygon 判断点在多边形内
如何判断一个点在多边形内部? xv= [0 3 3 0 0]; %x坐标 yv= [0 0 3 3 0];%y坐标 x=1.5; y=1.5; in=inpolygon(x,y,xv,yv) plot ...
- Hibernate的BaseDao辅助类
1.BaseDao接口类,该类封装了一些hibernate操作数据库的一些常用的方法,包括分页查询,使用该类极大的简化了hibernate的开发 BaseDao.java package com.kj ...
- .NET常用工具类集锦
不错的地址: http://www.cnblogs.com/flashbar/archive/2013/01/23/helper.html https://github.com/chrisyanghu ...
- 补丁安装命令(WUSA)
wusa windows6.1-kb2716513-x64.msu /quiet /norestart msxml4-kb2758694-enu.exe /quiet /norestart 安装.ms ...
- 经常使用的webservice接口
Web Service 一些对外公开的网络服务接口 2011-10-29 14:12 商业和贸易: 1.股票行情数据 WEB 服务(支持香港.深圳.上海基金.债券和股票:支持多股票同一时候查询) En ...
- 一个仿 github for windows 及 windows 8 的进度条
https://github.com/wly2014/ProgressBar
- android学习日记10--裁剪区域
裁剪区域 裁剪是画布的一个函数,区域可以是矩形和圆形,也可以通过设置 path 或Region来显示自定义区域,通过不同组合,Android几乎可以支持任意现状的裁剪区域.android.graphi ...
- a标签中关于javascript:void(0)的几个问题
最近看了好几个关于<a>标签和javascript:void(0)的帖子,谨记于此,以资查阅.注:以下代码未经全面测试,但每一种方法可能会出现的情况都基本做了说明. 在做页面时,如果想做一 ...
- html5刮刮卡
通过Canvas实现的可刮涂层效果. 修改img.src时涂层也会自动适应新图片的尺寸. 修改layer函数可更改涂层样式. 涂层: 可刮效果: 以下是HTML源代码(已增加移动设备支持): 1 2 ...
- javascript中window.event事件用法详解
转自http://www.jb51.net/article/32564.htm描述 event代表事件的状态,例如触发event对象的元素.鼠标的位置及状态.按下的键等等. event对象只在事件发生 ...