|
10 | 10 | 'brick_sort_parallel',
|
11 | 11 | 'heapsort',
|
12 | 12 | 'matrix_multiply_parallel',
|
13 |
| - 'counting_sort' |
| 13 | + 'counting_sort', |
| 14 | + 'bucket_sort', |
14 | 15 | ]
|
15 | 16 |
|
16 | 17 | def _merge(array, sl, el, sr, er, end, comp):
|
@@ -438,3 +439,110 @@ def matrix_multiply_parallel(matrix_1, matrix_2, num_threads):
|
438 | 439 | i, j).result()
|
439 | 440 |
|
440 | 441 | return C
|
| 442 | + |
| 443 | +def _bucket_sort_helper(bucket: Array) -> Array: |
| 444 | + for i in range(1, len(bucket)): |
| 445 | + key = bucket[i] |
| 446 | + j = i - 1 |
| 447 | + while j >= 0 and bucket[j] > key: |
| 448 | + bucket[j+1] = bucket[j] |
| 449 | + j -= 1 |
| 450 | + bucket[j+1] = key |
| 451 | + return bucket |
| 452 | + |
| 453 | +def bucket_sort(array: Array, **kwargs) -> Array: |
| 454 | + """ |
| 455 | + Performs bucket sort on the given array. |
| 456 | +
|
| 457 | + Parameters |
| 458 | + ========== |
| 459 | +
|
| 460 | + array: Array |
| 461 | + The array which is to be sorted. |
| 462 | + start: int |
| 463 | + The starting index of the portion |
| 464 | + which is to be sorted. |
| 465 | + Optional, by default 0 |
| 466 | + end: int |
| 467 | + The ending index of the portion which |
| 468 | + is to be sorted. |
| 469 | + Optional, by default the index |
| 470 | + of the last position filled. |
| 471 | +
|
| 472 | + Returns |
| 473 | + ======= |
| 474 | +
|
| 475 | + output: Array |
| 476 | + The sorted array. |
| 477 | +
|
| 478 | + Examples |
| 479 | + ======== |
| 480 | +
|
| 481 | + >>> from pydatastructs import DynamicOneDimensionalArray as DODA, bucket_sort |
| 482 | + >>> arr = DODA(int, [5, 78, 1, 0]) |
| 483 | + >>> out = bucket_sort(arr) |
| 484 | + >>> str(out) |
| 485 | + "['0', '1', '5', '78']" |
| 486 | + >>> arr.delete(2) |
| 487 | + >>> out = bucket_sort(arr) |
| 488 | + >>> str(out) |
| 489 | + "['0', '1', '78']" |
| 490 | +
|
| 491 | + References |
| 492 | + ========== |
| 493 | +
|
| 494 | + .. [1] https://en.wikipedia.org/wiki/Bucket_sort |
| 495 | +
|
| 496 | + Note |
| 497 | + ==== |
| 498 | +
|
| 499 | + This function does not support custom comparators as is the case with |
| 500 | + other sorting functions in this file. |
| 501 | + The ouput array doesn't contain any `None` value. |
| 502 | + """ |
| 503 | + start = kwargs.get('start', 0) |
| 504 | + end = kwargs.get('end', len(array) - 1) |
| 505 | + |
| 506 | + #Find maximum value in the list and use length of the list to determine which value in the list goes into which bucket |
| 507 | + max_value = None |
| 508 | + for i in range(start, end+1): |
| 509 | + if array[i] is not None: |
| 510 | + max_value = array[i] |
| 511 | + |
| 512 | + count = 0 |
| 513 | + for i in range(start, end+1): |
| 514 | + if array[i] is not None: |
| 515 | + count += 1 |
| 516 | + if array[i] > max_value: |
| 517 | + max_value = array[i] |
| 518 | + |
| 519 | + number_of_null_values = end - start + 1 - count |
| 520 | + size = max_value // count |
| 521 | + |
| 522 | + # Create n empty buckets where n is equal to the length of the input list |
| 523 | + buckets_list = [[] for _ in range(count)] |
| 524 | + |
| 525 | + # Put list elements into different buckets based on the size |
| 526 | + for i in range(start, end + 1): |
| 527 | + if array[i] is not None: |
| 528 | + j = array[i] // size |
| 529 | + if j is not count: |
| 530 | + buckets_list[j].append(array[i]) |
| 531 | + else: |
| 532 | + buckets_list[count-1].append(array[i]) |
| 533 | + |
| 534 | + # Sort elements within the buckets using Insertion Sort |
| 535 | + for z in range(count): |
| 536 | + _bucket_sort_helper(buckets_list[z]) |
| 537 | + |
| 538 | + # Concatenate buckets with sorted elements into a single array |
| 539 | + sorted_list = [] |
| 540 | + for x in range(count): |
| 541 | + sorted_list.extend(buckets_list[x]) |
| 542 | + for i in range(end, end - number_of_null_values, -1): |
| 543 | + array[i] = None |
| 544 | + for i in range(start, end - number_of_null_values + 1): |
| 545 | + array[i] = sorted_list[i-start] |
| 546 | + if _check_type(array, DynamicArray): |
| 547 | + array._modify(force=True) |
| 548 | + return array |
0 commit comments