Delphi Radix Sort 支持负整数

Posted

技术标签:

【中文标题】Delphi Radix Sort 支持负整数【英文标题】:Delphi Radix Sort supporting negative integers 【发布时间】:2020-08-16 09:08:43 【问题描述】:

最近我使用了来自 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,i], s[1,i-1]);
    Inc(s[2,i], s[2,i-1]);
    Inc(s[3,i], 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, m_temp, s[2], 16);
  Sort_step(m_temp, m, s[3], 24);

  SetLength(m_temp, 0);
end;

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

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

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

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

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

【问题讨论】:

忘了说:我用的是 Delphi 10.3。 SO 不是编码服务 @DavidHeffernan 是的,我知道这一点,但我觉得卡住了。如果有帮助,我可以在主帖中展示我是如何尝试完成的,也许有人会修复我的尝试。虽然我认为它们是垃圾。 10k 似乎是一个非常小的数组。你确定你需要基数排序吗? @DavidHeffernan 这是数组的最小大小。它可以上升。但是不,我不确定。 【参考方案1】:

一个简单的方法是在过程中的某个地方补充符号位。请注意,这只影响最重要的“数字”(通常是快速基数排序的字节)。处理最重要“数字”的代码可以在一个单独的循环中处理,而不是处理其他“数字”的代码。

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

【讨论】:

以上是关于Delphi Radix Sort 支持负整数的主要内容,如果未能解决你的问题,请参考以下文章

#19 基数排序(Radix Sort)

java Comparator.compare(T o1,To2) 返回负整数、正整数的意义

python十进制转二进制数组求解,急

$each $position $sort $slice

Comparators.sort (转载)

不超过 $10^{18}$ 的非负整数在模意义下的乘法