Talk:American flag sort
This article is rated Start-class on Wikipedia's content assessment scale. It is of interest to the following WikiProjects: | ||||||||||||||||||||||||||||||||||||||
|
The sample Python code does not properly sort the array
[edit]There is something wrong with the implementation or it is partial and needs to be changed.
from math import floor, log from copy import copy def get_radix_val(x, digit, radix): return int(floor(x / radix**digit)) % radix def compute_offsets(a_list, start, end, digit, radix): counts = [0 for _ in range(radix)] for i in range(start, end): val = get_radix_val(a_list[i], digit, radix) counts[val] += 1 offsets = [0 for _ in range(radix)] sum = 0 for i in range(radix): offsets[i] = sum sum += counts[i] return offsets def swap(a_list, offsets, start, end, digit, radix): i = start next_free = copy(offsets) cur_block = 0 while cur_block < radix-1: if i >= start + offsets[cur_block+1]: cur_block += 1 continue radix_val = get_radix_val(a_list[i], digit, radix) if radix_val == cur_block: i += 1 continue swap_to = next_free[radix_val] a_list[i], a_list[swap_to] = a_list[swap_to], a_list[i] next_free[radix_val] += 1 def american_flag_sort_helper(a_list, start, end, digit, radix): offsets = compute_offsets(a_list, start, end, digit, radix) swap(a_list, offsets, start, end, digit, radix) if digit == 0: return for i in range(len(offsets)-1): american_flag_sort_helper(a_list, offsets[i], offsets[i+1], digit-1, radix) def american_flag_sort(a_list, radix): for x in a_list: assert(type(x) == int) max_val = max(a_list) max_digit = int(floor(log(max_val, radix))) american_flag_sort_helper(a_list, 0, len(a_list), max_digit, radix) A = [((20*(x**3))//1)+67500 for x in range(-15,16)] print(A) import random random.shuffle(A) print(A) american_flag_sort(A, 4) print(A)
The output is:
[0, 12620, 23560, 32940, 40880, 47500, 52920, 57260, 60640, 63180, 65000, 66220, 66960, 67340, 67480, 67500, 67520, 67660, 68040, 68780, 70000, 71820, 74360, 77740, 82080, 87500, 94120, 102060, 111440, 122380, 135000] [74360, 60640, 111440, 32940, 65000, 66220, 0, 70000, 67500, 135000, 94120, 102060, 82080, 23560, 122380, 66960, 67480, 67520, 67340, 47500, 12620, 87500, 63180, 68780, 40880, 57260, 71820, 67660, 52920, 77740, 68040] [0, 32940, 66960, 52920, 23560, 40880, 57260, 74360, 60640, 12620, 65000, 47500, 63180, 67480, 67520, 67340, 66220, 70000, 67500, 68780, 68040, 71820, 67660, 77740, 94120, 87500, 82080, 111440, 102060, 122380, 135000]
The last array, which is result from the function, is not properly sorted. Different radixes give different results, but none of them are correct.
Tested using Python 3.4.3 on Linux x64.
80.220.91.165 (talk) 10:23, 24 November 2015 (UTC)
- Very late response, but this is correct, the provided Python code had several bugs. It was probably never tested. I'll go ahead and fix them. For future reference, the changes were as follows (I can't be arsed to summarize them considering how many bugs there were):
def compute_offsets(a_list, start, end, digit, radix): counts = [0 for _ in range(radix)] for i in range(start, end): val = get_radix_val(a_list[i], digit, radix) counts[val] += 1 - offsets = [0 for _ in range(radix)] - sum = 0 + offset = start + offsets = [start] for i in range(radix): - offsets[i] = sum - sum += counts[i] + offset += counts[i] + offsets.append(offset) return offsets def swap(a_list, offsets, start, end, digit, radix): - i = start next_free = copy(offsets) cur_block = 0 - while cur_block < radix-1: - if i >= start + offsets[cur_block+1]: + while cur_block < radix: + i = next_free[cur_block] + if i >= offsets[cur_block+1]: cur_block += 1 continue radix_val = get_radix_val(a_list[i], digit, radix) - if radix_val == cur_block: - i += 1 - continue - swap_to = next_free[radix_val] - a_list[i], a_list[swap_to] = a_list[swap_to], a_list[i] + if radix_val != cur_block: + swap_to = next_free[radix_val] + a_list[i], a_list[swap_to] = a_list[swap_to], a_list[i] next_free[radix_val] += 1
- I'd rather replace the whole thing with something else though. I might still do that a little later.
- MaksVerver (talk) 19:43, 27 July 2023 (UTC)
The original implementation is rather different--somewhat shorter, and much faster
[edit]See: Engineering Radix Sort, p. 16, and appendix program C. — Preceding unsigned comment added by 70.16.100.236 (talk) 20:03, 20 April 2018 (UTC)
Comparing "bytes" instead of objects
[edit]I just edited the page to say that American flag sort sorts on the basis of the bytes (mathematical representation) of the objects instead of a object-defined comparison.
I find this wording problematic because likening bytes to mathematical representation doesn't feel very accurate. Are there any better words out there? DesmondWillowbrook (talk) 17:20, 4 February 2023 (UTC)
- Start-Class United States articles
- Low-importance United States articles
- Start-Class United States articles of Low-importance
- WikiProject United States articles
- Start-Class Computer science articles
- Unknown-importance Computer science articles
- WikiProject Computer science articles
- Start-Class Computing articles
- Unknown-importance Computing articles
- All Computing articles