Delphi - 按高,低,高,低顺序对实数进行排序

时间:2013-05-12 13:53:50

标签: delphi sorting pascal

说我有数据 1,2,3,4,5,6

我想对这些数据进行排序,以便输出 6 1 5 2 4 3

这样,数字匹配,以便低数字与高数字配对

我会使用合并排序按数字顺序对其进行排序,然后根据这些条件拆分列表并匹配它们吗?

我正在尝试对从数据文件中读取的字符串网格中的实数数据进行排序;我有一个工作程序按数字顺序对这些数据进行排序,但我不知道如何编写它以便按高,低,高,低排序

这是我的网格排序的代码

procedure TForm1.SortGrid(Grid: TStringGrid; const SortCol: Integer;
//sorting the string grid
  const datatype: Integer; const ascending: boolean);
var
  i: Integer;
  tempgrid: TStringGrid;
  list: array of Integer;
begin
  tempgrid := TStringGrid.create(self);
  with tempgrid do
  begin
    rowcount := Grid.rowcount;
    ColCount := Grid.ColCount;
    fixedrows := Grid.fixedrows;
  end;
  with Grid do
  begin
    setlength(list, rowcount - fixedrows);
    for i := fixedrows to rowcount - 1 do
    begin
      list[i - fixedrows] := i;
      tempgrid.rows[i].assign(Grid.rows[i]);
end;
   Mergesort(Grid, list, SortCol + 1, datatype, ascending);


      for i := 0 to rowcount - fixedrows - 1 do
      begin
    rows[i + fixedrows].assign(tempgrid.rows[list[i]])
      end;
      row := fixedrows;
    end;
    tempgrid.free;
    setlength(list, 0);
  end;

4 个答案:

答案 0 :(得分:3)

首先,使用您想要的任何算法按降序对数字进行排序(我在示例中使用了冒泡排序)

然后,如果数组中有n个元素:

  • 设置一个从1到(n div 2)的计数器
  • 获取最后一个元素并将其存储在临时变量( tmp
  • (计数器 - 1)* 2 + 1 开始,将所有元素向右移动一个位置。这将覆盖最后一个元素,但您将其存储在 tmp var
  • 数组[(counter - 1)* 2 + 1] 元素设置为 tmp
  • 结束计数器

这样你就可以有效地从数组中获取最后一个元素并将其插入1,3,5 ...位置,直到你插入数组元素的后半部分。

示例代码:

procedure Sort(var AArray: array of Double);
var
  C1, C2: Integer;
  tmp   : Double;
  pivot : Integer;
begin
  for C1 := Low(AArray) to High(AArray) - 1 do
    for C2 := C1 + 1 to High(AArray) do
      if AArray[C1] < AArray[C2] then
      begin
        tmp := AArray[C1];
        AArray[C1] := AArray[C2];
        AArray[C2] := tmp;
      end;

  pivot := Length(AArray) div 2;
  for C1 := 1 to pivot do
  begin
    tmp := AArray[High(AArray)];
    for C2 := High(AArray) downto (C1 - 1) * 2 + 1 do
      AArray[C2] := AArray[C2 - 1];
    AArray[(C1 - 1) * 2 + 1] := tmp;
  end;
end;

答案 1 :(得分:2)

按升序对数据进行排序。然后使用以下索引选择值:0,n-1,1,n-2,....

在伪代码中,算法如下所示:

Sort;
lo := 0;
hi := n-1;
while lo<=hi do
begin
  yield lo;
  inc(lo);
  if lo>hi then break;
  yield hi;
  dec(hi);
end;

答案 2 :(得分:2)

从上面提供的示例数据中,我假设输入数组是预先排序的。

[请注意,我手边没有编译器,所以你必须运行它并看到它有效 - 可能需要进行小提琴。]

procedure SerratedSort(var AArray: array of Double);
var
  Length1: Integer;
  Index1: Integer;
  Temp1: Double;
begin
  Length1 := Length(AArray);
  Index1 := 0;
  while Index1 < Length1 do begin
    Temp1 := AArray[Length1 - 1];
    System.Move(AArray[Index1], AArray[Index1 + 1], (Length1 - Index1 + 1) * SizeOf(Double));
    AArray[Index1] := Temp1;
    Index1 := Index1 + 2;
  end;
end;

以下是它(应该)如何分步工作

输入AArray:123456

  • Index1:0
  

Temp1:= 6

     

System.Move:112345

     

AArray:612345

  • Index1:2
  

Temp1:= 5

     

System.Move:612234

     

AArray:615234

  • Index1:4
  

Temp1:= 4

     

System.Move:615233

     

AArray:615243

输出AArray:615243


对于记录结构,例如TPerson,它将是这样的:

procedure SerratedSort(var A: array of TPerson);
var
  s: Integer;
  i: Integer;
  t: TPerson;
begin
  s := Length(A);
  i := 0;
  while i < s do begin
    t := A[s - 1];
    System.Move(A[i], A[i + 1], (s - i + 1) * SizeOf(TPerson));
    A[i] := t;
    i := i + 2;
  end;
end;

答案 3 :(得分:1)

演示已经给出的解决方案的示例程序:

program Project1;

{$APPTYPE CONSOLE}

const
  Count = 12;
type
  TValues = array[0..Count - 1] of Double;
const
  Input: TValues = (1,2,4,9,13,14,15,23,60,100,101,102);
var
  I: Integer;
  Output: TValues;

procedure ShowValues(Caption: String; Values: TValues);
var
  I: Integer;
begin
  Write(Caption);
  for I := 0 to Count - 2 do
    Write(Round(Values[I]), ', ');
  WriteLn(Round(Values[Count - 1]));
end;

begin
  if Odd(Count) then
    WriteLn('Cannot compute an odd number of input values')
  else
  begin
    WriteLn('Program assumes sorted input!');
    ShowValues('Input:  ', Input);
    for I := 0 to (Count div 2) - 1 do
    begin
      Output[2 * I] := Input[I];
      Output[2 * I + 1] := Input[Count - 1 - I];
    end;
    ShowValues('Output: ', Output);
  end;
  ReadLn;
end.