0

假设我有数据 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

4 回答 4

3

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

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

  • 设置一个从 1 到 (n div 2) 的计数器
  • 取最后一个元素并将其存储在临时变量(tmp)中
  • (counter - 1) * 2 + 1开始,将所有元素向右移动一位。这将覆盖最后一个元素,但您将其存储在tmp var
  • array[(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;
于 2013-05-12T14:25:20.690 回答
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;

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

输入数组:123456

  • 索引1:0

温度 1 := 6

系统移动:112345

数组:612345

  • 索引1:2

温度 1 := 5

系统移动:612234

数组:615234

  • 指数1:4

温度 1 := 4

系统移动:615233

数组:615243

输出数组: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;
于 2013-05-12T16:43:52.403 回答
1

按升序对数据进行排序。然后使用以下索引选择值: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;
于 2013-05-12T14:17:38.470 回答
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.
于 2013-05-12T14:44:01.720 回答