指针操作无效;递归合并排序

时间:2018-01-18 23:16:59

标签: delphi recursion mergesort delphi-xe

我试图为字符串实现合并排序但是我无法执行递归部分而且我收到错误“无效的指针操作”

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var i : Integer;
const MyArray : array[1..5]of string = ('hi', 'zebra', 'apple', 'Xylophone', 'dog');

Procedure merge(result, left, right : array of string);
var i, i1, i2 : Integer;
begin
  i1 := 0;
  i2 := 0;
  for i := 0 to Length(result) do
  begin
    if (i2 >= Length(right)) or (i1 < Length(left)) and (StrComp(PChar(left[i]), PChar(right[i2])) < 0) then
    begin
      result[i] := left[i1];
      inc(i1);
    end
    else
    begin
      result[i] := right[i2];
      inc(i2);
    end;
  end;
end;


Procedure mergeSort(OriginalList : array of string);
var left, right : array of string;
    i : Integer;
begin
  if (Length(OriginalList) >= 2) then
  begin
    setlength(left, length(OriginalList) div 2);
    setlength(right, length(OriginalList) - (length(OriginalList) div 2));
    for i := 0 to Length(left) do
    begin
      left[i] := OriginalList[i];
    end;
    for i := 0 to Length(right) do
    begin
      right[i] := OriginalList[i + Length(OriginalList) div 2];
    end;
    mergeSort(left);
    mergeSort(right);
    merge(OriginalList, left, right);
  end;
end;

begin
  writeln('The data before sorting: ');
  for i := low(MyArray) to High(MyArray) do
  begin
    write(MyArray[i]+' ');
  end;
  writeln;
  mergeSort(MyArray);
  writeln('The data before sorting: ');
  for i := low(MyArray) to High(MyArray) do
  begin
    write(MyArray[i]+' ');
  end;
  readln;
end.

在mereSort函数的行中,我回想起数组“左”和“右”的合并排序函数,我收到错误信息,但我不太明白为什么?

1 个答案:

答案 0 :(得分:4)

这有很多不同之处,希望这些要点可以帮助你朝着正确的方向发展。

数组索引的问题

您正在超出数组末尾的索引: 动态数组从零开始索引,因此行

    for i := 0 to Length(left) do

应该是

    for i := 0 to Length(left) - 1 do

或者您可以使用

   for i := Low(left) to High(left) do

正如你后来做的那样。

我建议您选择一个标准表单并一致地使用它,并且除非您有充分的理由,否则您应该避免使用非零基础索引来声明常量数组,这样您可以一致地使用相同的表单或更改类型数组以后没有遇到麻烦

第一个修复程序会阻止您的程序崩溃,但您会注意到您的排序代码没有改变任何内容......

参数传递问题

Delphi有几种不同的方法可以将参数传递给程序:

procedure doSomething(a : array of string);
procedure doSomething(var a : array of string);
procedure doSomething(out a : array of string);
procedure doSomething(const a : array of string);

这些决定了程序中发生的事情如何影响传递的原始变量

这是您需要了解的内容,请在文档中阅读: http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Parameters_(Delphi)

IMO有一些非常令人困惑的行为和与数组参数相关的语法,很多东西看起来很直观,特别是对于XE /旧版本,它值得阅读有关标准数据类型的文档

在当前状态下,您的合并过程将无效,因为它只对您传入的数组的新副本进行操作,您也将其声明为常量

其他

我会避免使用result作为过程参数,因为这是用于函数返回值的名称,似乎要求使用它的麻烦。

PS:我没有看过合并的逻辑,只是基本的语言错误