基于链表实现的桶排序

27 篇文章 1 订阅
15 篇文章 0 订阅

1. 问题描述:使用桶排序算法对控制台输入的数字进行排序

2. 桶排序涉及到几个问题:

① 桶的大小,这里我们可以根据输入的元素的个数来确定桶的大小

② 怎么样确定当前元素进入哪一个桶,这里我们使用到的是通过一个哈希函数来进行计算

int index =  (element * length) / (max + 1);

element为当前元素的值,length为桶的大小,max为数组中最大元素的值

③ 因为输入的数据是随机的,所以有可能在一个桶中分布着好几个数据,那么怎么样维持在一个桶中的顺序呢?

因为涉及到桶中元素的数量的不确定性,所以我们可以使用动态的数据结构来存储,考虑到插入的操作是比较频繁的,所以这里我们使用链表来进行插入元素,并且在一个桶中维持从小到大的顺序

在一开始的时候我们扫描桶的元素,找到第一个比当前需要插入的元素大或者相等的的元素,那么将这个元素往前插入就可以了

解决了上面的问题之后那么我们就可以写代码了

3. 具体的代码如下:

import java.util.Scanner;
public class Main{
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int arr[] = new int[n];
		for(int i = 0; i < n; i++){
			arr[i] = sc.nextInt();
		}
		sortByBucket(arr);
		sc.close();
	}

	private static void sortByBucket(int[] arr){
		int length = arr.length;
		LinkedNode bucket[] = new LinkedNode[length];
		//System.out.println(bucket.length);
		int max = Util.maxOf(arr);
		for(int i = 0; i < length; i++){
			int index = hash(arr[i], length, max);
			if(bucket[index] == null){
				bucket[index] = new LinkedNode(arr[i]);
			}else{
				insertInto(arr[i], bucket[index], index, bucket);
			}
		}	
		int k = 0;
		for (LinkedNode node : bucket) {
		    if (node != null) {
		       while (node != null) {
		          arr[k++] = node.value;
		          node = node.next;
		       }
		     }
		}
		for(int i = 0; i < length; i++){
			System.out.print(arr[i] + " ");
		}	
	}

	private static void insertInto(int element, LinkedNode head, int index, LinkedNode[] bucket){
		LinkedNode newNode = new LinkedNode(element);
		if(element <= head.value){
			newNode.next = head;
			bucket[index] = newNode;
			return;
		}
		LinkedNode p = head;
		LinkedNode pre = p;
		while(p != null && element > p.value){
			pre = p;
			p = p.next;
		}
		if(p == null){
			pre.next = newNode;
		}else{		
			pre.next = newNode;
			newNode.next = p;
		}
	}

	private static int hash(int element, int length, int max) {
		return (element * length) / (max + 1);
	}	
}

4. 时间复杂度的问题

时间复杂度: O(N+C),其中C=N*(logN-logM),M为桶的个数

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值