算法(6)桶排序 //续上篇

        周末了,才终于有时间把没写完的算法接着写下去。先来看上面那篇的代码。

#include<vector>  
#include<iostream>  
  
using namespace std;  
  
void bucketSort(vector<int>& vec)  
{  
    int length=vec.size();  
    vector<int> buckets(length,0);//准备一堆桶,容器的下标即待排序数组的键值或键值经过转化后的值  
    //此时每个桶中都是没有放蛋的,所以都是0  
  
    for(int i=0;i<length;++i)  
    {  
        buckets[vec[i]]++;//把每个蛋放入到对应的桶中  
    }  
      
    int index=0;  
    for(int i=0;i<length;++i)  
    {//把蛋取出,空桶则直接跳过  
        for(int j=0;j<buckets[i];j++)  
        {  
            vec[index++]=i;  
        }  
    }  
}  
//上例是直接将键值作为桶下标的程序,没有经过转化  
  
int main()  
{  
    int a[10]={0,2,5,6,3,2,5,9,5,2};  
    vector<int> vec(a,a+10);  
  
    bucketSort(vec);  
    for(int i=0;i<vec.size();++i)  
    {  
        cout<<vec[i]<<"   ";  
    }  
    return 0;  
} 

        这个程序看似没什么问题,其实问题很多。
        1.设计桶的时候,将原数组的长度作为桶的个数,但是对桶内放东西的时候,用的却是bucket[vec[i]]++,如果原数组内的元素大于数组的长度,桶的这个数组不就越界了嘛!还好是vector动态数组看不出来。
        2.将原数组内的值作为桶的编号这本身就不合理,如果数组元素再多些,对于内存空间是巨大的浪费,桶排序的精髓是将大范围的映射到小范围来,这违背了算法的初衷。
        3.最后从桶内取数据的时候用的是计数排序的方法,从这个角度看这更像是计数排序而不是桶排序。


        下面是我写的代码,桶内的排序用了之前的插入排序。写完代码发现已经凌晨12:30了,程序员果然是夜行动物,还好是周末,一边吃火龙果一边写代码。

#include<vector>  
#include<iostream>  
#include<cmath>
  
using namespace std;  
 
 void show_vec(vector<int> vec)  
{  
    cout<<endl;  
    for(int i=0;i<vec.size();i++)  
    cout<<vec[i]<<"   ";  
    cout<<endl;  
}  
int max(vector<int> vec)   //find min
{  
    int max=vec[0];  
    for(int i=0;i<vec.size();i++)  
        if(vec[i]>max)  
            max=vec[i];        
    return max;  
} 

int min(vector<int> vec)  //find min
{  
    int min=vec[0];  
    for(int i=0;i<vec.size();i++)  
        if(vec[i]<min)  
            min=vec[i];        
    return min;  
} 

void insert_sort(vector<int> &vec)  
{  
    int temp,j;  
    for(int i=1;i<vec.size();i++)  //the remain card  
        {  
            temp=vec[i];  
            for(j=i-1;j>=0;j--)  //card in hand ,search from the back  
            {  
                if(temp<vec[j])  
                    vec[j+1]=vec[j]; //find? no,move  
                else  
                    break;       //find? yes.this a[j]>temp,so temp should be put in a[j+1]  
            }  
            vec[j+1]=temp;  
              
        }  
} 
void put_into_bucket(vector<int> &vec,vector<vector<int>> &bucket)  //put the original into bucket
{
	int max_num=max(vec);
	int min_num=min(vec);
	int index=0;
	for(int i=0;i<vec.size();i++)  // 10 bucket ,0-9
	{
		if(vec[i]==max_num)
		{
			bucket[9].push_back(max_num);
			continue;
		}
		if(vec[i]==min_num)
		{
			bucket[0].push_back(min_num);
			continue;
		}
		index=floor((vec[i]-min_num)*10/(max_num-min_num));
		bucket[index].push_back(vec[i]);
	}
}
void bucket_sort(vector<int>& vec)  
{  
	int index=0;
	vector<vector<int>> bucket(10);
	
	put_into_bucket(vec,bucket);
	
	for(int i=0;i<10;i++)
	{
		insert_sort(bucket[i]);
	}
	
	for(int i=0;i<10;i++)
	{
		for(int j=0;j<bucket[i].size();j++)
		{
			vec[index++]=bucket[i][j];
		}
	}
     
}  
 
  
int main()  
{  
    int a[5]={11,16,22,12,7};  
    vector<int> vec(a,a+5);  
  
    bucket_sort(vec);  
    show_vec(vec);
    return 0;  
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值