背景:
引理 1 :令是深度为的二叉树,则最多有片树叶【数学归纳法】
引理 2 :具有片树叶的的二叉树的深度至少为【由引理1可得】
定理 1 :只使用元素间比较的任何排序算法在最坏情况下至少需要次比较。【对个元素排序,必然有片数树叶】
定理 2 :只是用元素间比较的任何排序算法需要次比较。
由定理 2可知,任何只是用比较的一般排序算法在最坏的情况下需要运行时间,但是在特殊情况下,仍可以实现线性时间排序。一个简单的例子即为桶排序(bucketSort)。桶排序之所以能以线性时间运行在于,桶排序使用了比简单的比较更为强大的操作。
尽管桶排序看似一般而用处不大,但实际上存在许多输入只是小的整数的情况,使用诸如快速排序这样的算法就有点小题大做了。
桶排序(bucketSort):
输入数据必须只由小于的正整数构成,使用一个大小为的数组并初始化为0,统计的个数,然后扫描,打印排序后的结果。该算法的时间复杂度为。
行为描述:
算法描述:
第一步:遍历,将装入,并统计出现的次数;
第二步:遍历,判断将赋值给
桶排序实例:
//bucketSort.cpp
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
template<class T>
void bucketSort(vector<T> &v){
typename vector<T>::iterator itr = max_element(v.begin(), v.end());
//cout << " max value : " << *itr << endl;
vector<T> bucket((int)*itr + 1);
//count the v[i] times and locate the position
for(int i = 0; i < v.size(); i++){
bucket[v[i]]++;
}
//rewrite v in order
for(int i = 0, j = 0; i < bucket.size(); i++){
while( (bucket[i]--) > 0){
v[j++] = i;
}
}
bucket.clear();
}
int main(){
//int arr[] = {81, 94, 11, 96, 12, 35, 17, 95, 28, 58, 41, 75, 15};
int arr[] = {2, 3, 3, 4, 2, 5, 6, 7, 4, 5, 8};
int len = sizeof(arr) / sizeof(arr[0]);
vector<int> v;
for(int i = 0 ; i < len; i++){
v.push_back(arr[i]);
}
cout << "******* the original data ***********" << endl;
for(typename vector<int>::iterator itr = v.begin(); itr != v.end(); ++itr){
cout << *itr << " ";
}
cout << endl;
cout << "******* the sorted data ***********" << endl;
bucketSort(v);
for(typename vector<int>::iterator itr = v.begin(); itr != v.end(); ++itr){
cout << *itr << " ";
}
cout << endl;
cout << " done ." << endl;
return 0;
}
practice makes perfect !