zoukankan      html  css  js  c++  java
  • 9. 桶排序

    思想

    桶排序,也是为了解决计数排序计数数组大小设置的问题。桶排序,就是把待排序数据分为不同的区间,然后区间内进行排序,最后即可完成排序。

    就有点像,成绩会有一个区间,比如100-90, 90-80这样,每个区间就是一个桶,然后对桶内元素进行排序。最后取出来,即完成排序。

    从上面分析可以看出,我们对区间排序的时候,最好每个区间(桶)中数据是均匀的。

    至于如何对桶内元素进行排序?这个是一个困惑,网上很多给的实例,是直接调用 api 的排序函数。

    维基百科上,是对桶内数据采用插入排序的方法。

    我个人偏向于第二种。

    第一种有点投机取巧,虽然Java中的排序函数,会根据数据量的大小选用不同的排序函数,因为不同的数据量,不同的排序函数的时间效率还是有点差别的。java中的排序函数应该会根据数据量大小,调用相对高效的排序函数。

    这里还得知道,在数据量较小的情况下,插入排序比快排和归并要高效。因为桶分数据,相对假设每个桶的数据都比较少,所以个人偏向桶内排序采用插入排序。

    实现

    贴出维基百科上的代码

    private int indexFor(int a, int min, int step) {
    		return (a - min) / step;
    	}
    
    	public void bucketSort(int[] arr) {
    
    		int max = arr[0], min = arr[0];
    		for (int a : arr) {
    			if (max < a)
    				max = a;
    			if (min > a)
    				min = a;
    		}
    		// 該值也可根據實際情況選擇
    		int bucketNum = max / 10 - min / 10 + 1;
    		List buckList = new ArrayList<List<Integer>>();
    		// create bucket
    		for (int i = 1; i <= bucketNum; i++) {
    			buckList.add(new ArrayList<Integer>());
    		}
    		// push into the bucket
    		for (int i = 0; i < arr.length; i++) {
    			int index = indexFor(arr[i], min, 10);
    			((ArrayList<Integer>) buckList.get(index)).add(arr[i]);
    		}
    		ArrayList<Integer> bucket = null;
    		int index = 0;
    		for (int i = 0; i < bucketNum; i++) {
    			bucket = (ArrayList<Integer>) buckList.get(i);
    			insertSort(bucket);
    			for (int k : bucket) {
    				arr[index++] = k;
    			}
    		}
    
    	}
    
    	// 把桶內元素插入排序
    	private void insertSort(List<Integer> bucket) {
    		for (int i = 1; i < bucket.size(); i++) {
    			int temp = bucket.get(i);
    			int j = i - 1;
    			for (; j >= 0 && bucket.get(j) > temp; j--) {
    				bucket.set(j + 1, bucket.get(j));
    			}
    			bucket.set(j + 1, temp);
    		}
    	}
    

    需要注意的是,桶的数据结构,是采用arraylist接arraylist。

    下图中是链表形式,所以我涂改了,应该是arraylist而不是链表。

    复杂度

    复杂度分析的话,主要是取决于每个桶中的时间复杂度。

    如果桶为很多,每个桶中只有一个数据,那么其实就是计数排序。

  • 相关阅读:
    ssh框架整合
    spring事务管理
    spring AOP
    spring静态代理和动态代理
    log4j介绍
    Socket通信介绍
    C# 串口与窗体应用程序的连接
    Halcon中的图像相减算子abs_diff_image和sub_image
    R-CNN、fast-RCNN、faster-RCNN到yolo、SSD简要
    QT入门系列(2):MinGW与MSVC编译的区别
  • 原文地址:https://www.cnblogs.com/zhouzhiyao/p/12532125.html
Copyright © 2011-2022 走看看