使用链接列表进行存储桶排序

时间:2014-02-15 20:22:36

标签: java bucket-sort

我正在尝试在Java中实现存储桶排序,以便对整数数组进行排序。我正在尝试使用链接列表作为我的桶,但在理解如何操作时遇到一些麻烦。任何人都可以提供实施吗?

我已经提供了这个算法,但它对我没有多大意义: enter image description here

4 个答案:

答案 0 :(得分:4)

由于您没有要分析的代码,我会给出一个书面答复。创建一个Bucket类,它包含两个数字(0-9,10-19等)之间的范围,一个insert方法(按顺序插入),并包含一个空数组。然后创建一个Buck List列表:

enter image description here

循环输入列表并将每个数字插入Bucket List中的相应Bucket。当您插入值时,它将为您排序。最后,将所有Bucket的数组和块一起放到输出列表中。

以下是Wikipedia的逐步处理:

  1. 设置一个最初为空的“桶”数组。
  2. 分散:遍历原始数组,将每个对象放入其存储桶中。
  3. 对每个非空桶进行排序。
  4. 收集:按顺序访问存储桶并将所有元素放回原始数组中。
  5. 这是您提供的算法:

    enter image description here

    这个简单转换为:

    1. A是您必须排序的输入数组
    2. n是输入数组A
    3. 的长度
    4. 您必须将输入数组A的所有元素插入到存储桶列表中B
    5. 现在在Bucket列表B中订购每个Bucket。
    6. 创建一个新的列表/数组以返回所有已订购的Bucket列表。
    7. 注意:第4步实际上可以根据您的实施执行第3步。

      此算法不会涉及您必须编码的复杂细节。这只是一个帮助您入门的简单指南。

答案 1 :(得分:1)

您可以开始分析:bucket example

答案 2 :(得分:0)

嗯,我不知道java,但我仍然可以给你算法。

最简单的方法是以数组的形式生成存储桶,其中每个数组索引指向一个空链表。

for each integer :  
   integer goes to bucket i  // bucket number depends on your implementation 
   pointer = bucket[i]   

   while pointer is not NULL  
      pointer = pointer->next  

   allocate new node
   pointer points to this node
   pointer.data = integer  
   pointer.next = NULL 

答案 3 :(得分:0)

您需要一些方法来计算您要排序的每个元素需要进入哪个存储桶 - 您可以创建一个接口,为您提供一些可以调用的常用方法:

public interface Indexable {
    public int getIndex();
}

然后你可以实现这样的桶排序算法:

public static <T extends Indexable> LinkedList<T> BucketSort( ArrayList<T> listToSort )
{
    // work out how many buckets you need.
    int max = 0;
    for ( T listElement : listToSort )
        max = Math.max( max, listElement.getIndex() );

    // initialise the buckets.
    ArrayList<LinkedList<T>> buckets = new ArrayList<LinkedList<T>>( max );
    for ( int i = 0; i <= max; ++i )
        buckets.add( new LinkedList<T>() );

    // add items to the buckets.
    for ( T listElement : listToSort )
        buckets.get( listElement.getIndex() ).addLast( listElement );

    // concatenate the buckets into a single list.
    LinkedList<T> result = new LinkedList<T>();
    for ( LinkedList<T> bucket : buckets )
        result.addAll( bucket );

    return result;
}

使用Indexable接口的实现对此进行测试,该接口存储整数并根据单位数字将其分配给存储桶:

public static class IndexableInteger implements Indexable {
    private final int value;

    public IndexableInteger( int value ) {
        this.value = value;
    }

    public int getIndex() {
        return value % 10;
    }

    public String toString(){
        return Integer.toString( value );
    }
}

然后这个:

public static void main(String[] args) {
    ArrayList<IndexableInteger> ints = new ArrayList<IndexableInteger>();
    int[] values = { 45, 71, 16, 31, 0, 25, 6, 51, 40, 81 };
    for ( int v : values )
        ints.add( new IndexableInteger( v ) );

    LinkedList<IndexableInteger> sorted = BucketSort( ints );
    System.out.println( sorted );
}

输出此数字(数字按最后一位数字排列,但如果它们具有相同的最后一位数字,则它们与输入的顺序相同):

[0, 40, 71, 31, 51, 81, 45, 25, 16, 6]

注意:你可能不想使用LinkedList,因为它的addAll()方法在线性时间而不是恒定时间运行但它很容易用于演示,这就是我使用的原因它在这里。