chapter_sorting/bucket_sort/ #440
Replies: 22 comments 40 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.
-
如果把排序理解为从一个初位置移动到最终位置,那么桶排序之所以快的原因是因为在放入桶的过程中某种意义就完成了粗略的排序。从快排的视角来看,就像是有k个哨兵,然后哨兵范围的相对顺序都整理好了 |
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.
-
js最后一步合并各桶可以这样简写: return buckets.flat(Infinity) |
Beta Was this translation helpful? Give feedback.
-
chapter_sorting/bucket_sort/
一本动画图解、能运行、可提问的数据结构与算法入门书
https://www.hello-algo.com/chapter_sorting/bucket_sort/
Beta Was this translation helpful? Give feedback.
All reactions