chapter_sorting/bucket_sort/ #440
Replies: 31 comments 44 replies
-
这个结构有点像链式地址实现的哈希表 |
Beta Was this translation helpful? Give feedback.
-
最坏情况的时间复杂度为什么是O(n^2)呢? |
Beta Was this translation helpful? Give feedback.
-
合并结果那里是不是应该是遍历K个桶? |
Beta Was this translation helpful? Give feedback.
-
第九行:应该改为:i = int(num % k),不是:i = int(num*k) |
Beta Was this translation helpful? Give feedback.
-
笔记: |
Beta Was this translation helpful? Give feedback.
-
C++: // 建堆
int k = nums.size() / 2;
auto min_it = min_element(nums.begin(), nums.end());
int min_value = *min_it;
vector<vector<int>> buckets(k);
for (int num : nums) {
int i = (num - min_value) % k; // 分桶
buckets[i].push_back(num);
} |
Beta Was this translation helpful? Give feedback.
-
「桶排序 bucket sort」是分治策略的一个典型应用。它通过设置一些具有大小顺序的桶,每个桶对应一个数据范围,将数据平均分配到各个桶中;然后,在每个桶内部分别执行排序;最终按照桶的顺序将所有数据合并。 |
Beta Was this translation helpful? Give feedback.
-
桶排序使用了内置的排序算法 sort,但是 sort 的时间复杂度是 O(nlogn),然后嵌套在 for 循环中,这不是时间复杂度更高了么? 是因为桶的数量是固定数量(常数级),因此这里的 sort 的时间复杂度就是一个常数级别 O(1) 么? 这里有点疑惑,望解惑 |
Beta Was this translation helpful? Give feedback.
-
大佬,cpp实现的桶内排序至少得是stable_sort, 这样清晰的指出以免误导后来者 |
Beta Was this translation helpful? Give feedback.
-
大神,c语言代码里 : // 1. 将数组元素分配到各个桶中
for (int i = 0; i < size; i++) {
// 输入数据范围为 [0, 1),使用 num * k 映射到索引范围 [0, k-1]
int bucket_idx = nums[i] * k;
int j = 0;
// 如果桶中有数据且数据小于当前值 nums[i], 要将其放到当前桶的后面,相当于 cpp 中的 push_back
while (buckets[bucket_idx][j] > 0 && buckets[bucket_idx][j] < nums[i]) {
j++;
}
float temp = nums[i];
while (j < ARRAY_SIZE && buckets[bucket_idx][j] > 0) {
swap(&temp, &buckets[bucket_idx][j]);
j++;
} 这段代码将元素放入桶中的时候感觉已经将桶里的元素给排序了,是我理解错了吗? |
Beta Was this translation helpful? Give feedback.
-
nlogn/k,为什么k很大时,趋近于n呢? |
Beta Was this translation helpful? Give feedback.
-
学习算法的的好方法 |
Beta Was this translation helpful? Give feedback.
-
桶排序在对每个桶进行快排的时候,不是也用了比较吗?这样是算非比较排序吗? |
Beta Was this translation helpful? Give feedback.
-
映射函数的选取:index := (nums[i] - minNum) / bucketSize //减去最小值,然后查看对应的索引在哪 |
Beta Was this translation helpful? Give feedback.
-
图11-15是不是有点问题,不过不影响整体理解,μ=25的话,10-25与25-80的区间长度明显不匹配 |
Beta Was this translation helpful? Give feedback.
-
桶排序的C语言实现,桶内排序采用插入排序 void insertion_sort(float *arr, int size) {
for (int i = 1; i < size; i++) {
float key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
void bucket_sort(float *arr, int size, int k = 4){
float *buckets[k], max_val, min_val, interval; int bucket_size[k], idx; if (size > 0) { max_val = arr[0]; min_val = arr[0];} // 最大最小值用于计算桶间隔
for (int i = 0; i < k; i++) { buckets[i] = (float *)malloc(sizeof(float) * size); bucket_size[i] = 0; }
for (int i = 1; i < size; i++) { if (arr[i] > max_val) max_val = arr[i]; if (arr[i] < min_val) min_val = arr[i]; } interval = (max_val - min_val) / k; if (max_val == min_val) return; // 计算桶的间隔;如果最大值和最小值相等,直接返回; 避免出现后续的除以0的情况
for (int i = 0; i < size; i++) { idx = (int)((arr[i] - min_val) / interval); if (idx >= k) idx = k - 1; buckets[idx][bucket_size[idx]++] = arr[i]; } // 计算当前元素所属的桶;当 arr[i] 恰好等于 max_val 时,idx 会计算为 k,而 k 是桶的数量,这会导致数组越界。
for (int i = 0; i < k; i++) { insertion_sort(buckets[i], bucket_size[i]); } // 对每个桶进行排序
idx = 0; for (int i = 0; i < k; i++) { for (int j = 0; j < bucket_size[i]; j++) { arr[idx++] = buckets[i][j]; } free(buckets[i]); } // 将桶中的元素取出
} |
Beta Was this translation helpful? Give feedback.
-
桶排序的C语言实现,桶内排序采用快速排序 int compare_floats(const void *a, const void *b) {
float fa = *(const float*)a;
float fb = *(const float*)b;
return (fa > fb) - (fa < fb); // fa > fb 返回正数, fa < fb 返回负数, 相等返回0
}
void bucket_sort(float *arr, int size, int k = 4){
float *buckets[k], max_val, min_val, interval; int bucket_size[k], idx; if (size > 0) { max_val = arr[0]; min_val = arr[0];} // 最大最小值用于计算桶间隔
for (int i = 0; i < k; i++) { buckets[i] = (float *)malloc(sizeof(float) * size); bucket_size[i] = 0; }
for (int i = 1; i < size; i++) { if (arr[i] > max_val) max_val = arr[i]; if (arr[i] < min_val) min_val = arr[i]; } interval = (max_val - min_val) / k; if (max_val == min_val) return; // 计算桶的间隔;如果最大值和最小值相等,直接返回; 避免出现后续的除以0的情况
for (int i = 0; i < size; i++) { idx = (int)((arr[i] - min_val) / interval); if (idx >= k) idx = k - 1; buckets[idx][bucket_size[idx]++] = arr[i]; } // 计算当前元素所属的桶;当 arr[i] 恰好等于 max_val 时,idx 会计算为 k,而 k 是桶的数量,这会导致数组越界。
for (int i = 0; i < k; i++) { qsort(buckets[i], bucket_size[i], sizeof(float), compare_floats); } // 对每个桶进行排序
idx = 0; for (int i = 0; i < k; i++) { for (int j = 0; j < bucket_size[i]; j++) { arr[idx++] = buckets[i][j]; } free(buckets[i]); } // 将桶中的元素取出
} |
Beta Was this translation helpful? Give feedback.
-
import random
def sort(nums):
k = len(nums) // 2
buckets = [[] for _ in range(k)]
new_nums = []
for num in nums:
buckets[int(num * k)].append(num)
for bucket in buckets:
bucket.sort()
new_nums.extend(bucket)
return new_nums
# nums = [random.random() for _ in range(10)]
nums = [random.randrange(0, 100) / 100 for _ in range(10)]
print(nums)
print(sort(nums))
|
Beta Was this translation helpful? Give feedback.
-
这里的空间复杂度为什么不是 O(n)? |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
js最后一步合并各桶可以这样简写: return buckets.flat(Infinity) |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
离散数学?二项分布、泊松分布妙,妙啊(doge |
Beta Was this translation helpful? Give feedback.
-
上面浮点数范围 [0, 1) 的桶排序,桶索引index = int(num * bucket_count)下面实现整数和负数的整数和负数的桶排序,桶索引index = (num + offset) // bucket_sizedef bucket_sort(nums, bucket_count):
"""
桶排序算法
:param nums: 待排序的数组
:param bucket_count: 桶的数量
:return: 排序后的数组
"""
# 找到数组中的最小值
min_val = min(nums)
# 找到数组中的最大值
max_val = max(nums)
# 计算索引偏移量,用于将所有元素转换为非负数
offset = -min_val
# 计算每个桶的大小
# 确保桶的大小至少为 1,避免出现桶大小为 0 的情况
bucket_size = max(1, (max_val - min_val) // bucket_count + 1)
# 初始化桶,创建 bucket_count 个空桶
buckets = [[] for _ in range(bucket_count)]
# 将数组中的元素分配到各个桶中
for num in nums:
# 计算元素 num 应该分配到的桶的索引
index = (num + offset) // bucket_size
# 将元素 num 添加到对应的桶中
buckets[index].append(num)
# 对每个桶中的元素进行排序
# 这里使用 Python 的内置排序函数
for bucket in buckets:
bucket.sort()
# 合并所有桶中的元素,将排序后的结果写回原数组 nums
i = 0 # 原数组的索引
for bucket in buckets:
for num in bucket:
nums[i] = num # 将排序后的元素写回原数组
i += 1 # 索引加 1
return nums |
Beta Was this translation helpful? Give feedback.
-
感觉这个也可以用于任意数吧,不一定是[0,1);关键看怎么塞到桶里。
|
Beta Was this translation helpful? Give feedback.
-
day09 |
Beta Was this translation helpful? Give feedback.
-
合并结果时需要遍历所有桶和元素,花费 O(n + k) 时间 |
Beta Was this translation helpful? Give feedback.
-
不明白为什么桶排序不属于基于比较的排序哇,每个桶的内部不还是基于比较的排序算法嘛 |
Beta Was this translation helpful? Give feedback.
-
c语言代码我看出两个问题 |
Beta Was this translation helpful? Give feedback.
-
疑问:为什么时间复杂度为O(n + k) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
chapter_sorting/bucket_sort/
一本动画图解、能运行、可提问的数据结构与算法入门书
https://www.hello-algo.com/chapter_sorting/bucket_sort/
Beta Was this translation helpful? Give feedback.
All reactions