支持负整数的Delphi Radix Sort

问题描述

最近,我使用了由Habr.com的Rebuilder制作的出色的排序算法。它对我很有用,但它只对正整数排序,最近我也遇到了对负数排序的需求。现在我使用QuickSort,但是由于数组很大(超过10k个元素),我想知道是否可以修改RadixSort来完成这项任务。

有目前为止的程序。评论翻译是我的,对不起,如果我遇到问题。

procedure RSort(var m: array of Longword);
//--------------------------------------------------
   procedure Sort_step(var source,dest,offset: array of Longword; const num: Byte);
   var i,temp : Longword;
       k : Byte;
   begin
     for i := High(source) downto 0 do
     begin
       temp := source[i];
       k := temp SHR num;
       dec(offset[k]);
       dest[offset[k]] := temp;
     end;
   end;
//--------------------------------------------------
// Объявляем массив корзин первым,для выравнивания на стеке
// Creating the bin array first for aligning at the stack
var s : array[0..3] of array[0..255] of Longword;
    i,k : longword;
    // Смещение байт внутри переменной k
    // Byte offset inside of variable k
    offset : array[0..3] of byte absolute k;
    m_temp : array of Longword;
begin
  SetLength(m_temp,Length(m));
  // Быстрая очистка корзин
  // Quick bin clear
  FillChar(s[0],256 * 4 * SizeOf(Longword),0);

  // Заполнение корзин
  // Filling bins
  for i := 0 to High(m) do
  begin
    k := m[i];
    Inc(s[0,offset[0]]);
    Inc(s[1,offset[1]]);
    Inc(s[2,offset[2]]);
    Inc(s[3,offset[3]]);
  end;

  // Пересчёт смещений для корзин
  // Recalculating bin offsets
  for i := 1 to 255 do
  begin
    Inc(s[0,i],s[0,i-1]);
    Inc(s[1,s[1,i-1]);
    Inc(s[2,s[2,i-1]);
    Inc(s[3,s[3,i-1]);
  end;

  // Вызов сортировки по байтам от младших к старшим
  // Sorting by byte,from least to most
  Sort_step(m,m_temp,s[0],0);
  Sort_step(m_temp,m,s[1],8);
  Sort_step(m,s[2],16);
  Sort_step(m_temp,s[3],24);

  SetLength(m_temp,0);
end;

链接https://habr.com/ru/post/484224/

我在互联网including StackOverflow上找到了一些有用的建议,但遇到了两个问题:

  1. 有太多不同的解决方案,我无法为Delphi选择最佳解决方案。

  2. 我缺乏正确实施它们的知识和技能。我尝试了一些但得到了错误的结果。

那么,有人可以修改给定的功能并向我解释他们做了什么,为什么?

解决方法

一种简单的方法是在处理过程中的某处补充符号位。请注意,这仅影响最高有效的“数字”(通常是用于快速基数排序的字节)。可以将处理最高有效“数字”的代码与处理其他“数字”的代码分开处理。

最简单的方法是进行一次初始遍历以补充数组中每个元素的符号位,进行基数排序,然后进行一次最终遍历再次对每个元素的符号位进行补充。