Помощь - Поиск - Пользователи - Календарь
Полная версия: Индексная сортировка слиянием
Форум «Всё о Паскале» > Delphi, Assembler и другие языки. > Delphi
RussoTuristo
Сортировка слиянием работает, сортирует всё нормально, нужно добавить индексы ....
На лекции было сказано, что достаточно добавить какой-либо тип, например: tIndexArray= array [1..1000] of integer;
И, НАПРИМЕР, вместо условий if A[i]>A[j] then Swap(A[i],A[j]) написать if A[P[i]]>A[P[j]] then Swap(P[i],P[j])

А на деле всё походу сложнее(нужно менять параметры в процедурах ...) и у меня одни косяки получаются, уже запутался где что менятЬ! Если кто-нибудь может помочь или подсказать, помогите пожалуйста.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Spin, TeEngine, Series, ExtCtrls, TeeProcs, Chart;

type

  tSortArray = array [1..1000] of integer;
  tIndexArray= array [1..1000] of integer;
  tSortType = integer;

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ListBox1: TListBox;
    ListBox2: TListBox;
    seElCount: TSpinEdit;
    Chart1: TChart;
    Series1: TLineSeries;
    Series2: TLineSeries;
    Button3: TButton;
    Chart2: TChart;
    Series3: TLineSeries;
    Series4: TLineSeries;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
   public
   SW:integer;
   procedure ShowVectorInList(List:TListBox; Src:TSortArray);

  end;

var
  Form1: TForm1;
  AR1,AR2: tSortArray;
  SW:integer;

implementation

{$R *.dfm}

function log(x,b: real):real;
begin
result:=ln(x)/ln(b);
end;


function CHB: integer; {определение выбранного кол-ва компонент}
begin
  Result:=Form1.seElCount.Value;
end;

function Merge({P:tIndexArray;} src: TSortArray; var Dest:TSortArray; L,M,H: integer):integer;
//выполняет слияние 2-х половин массива src от L до M - нижняя,
//от M+1 до H - верхняя в массив Dest
var i,j,k: integer;
Begin
  Result:=0;
  i:=L;   // первый элемент последовательности
  j:=M+1; // первый элемент второй половины последовательности
  k:=L;   // место, куда записываем
  //пока не закончилась одна из половин
  while (i<=M)and(j<=H) do
  begin
    if src[i]<src[j] then   // после просмотра записываем i-й элемент
      begin
        Dest[k]:=src[i];
        inc(i);
        inc(Result); // перестановка!
      end
    else
    begin
      Dest[k]:=src[j];    // после просмотра записываем j-й элемент
      inc(j);
      inc(Result); // перестановка!
    end;
    inc(k);
  end;
  //записываем оставшиеся элементы
  if i>M then // дописываем правую половину
  while j<=H do
    begin
      Dest[k]:=src[j];
      inc(j); inc(k);
      inc(Result); // перестановка!
    end
  else
  while i<=M do
    begin      // дописываем левую половину
      Dest[k]:=src[i];
      inc(i); inc(k);
      inc(Result); // перестановка!
    end;
end;

{Процедура расщепления}
function Split(L,H: integer; var src: TSortArray; var Dest: TSortArray):integer;
var M: integer;
// при первом обращении к данной процедуре массив Dest содержит копию src
Begin
  Result:=0;
  M:=(L+H) div 2; // середина последовательности
  // последовательность не элементарная => требуется разбиение
  If L<>H then
    begin
      Result:=Result+Split(L,M,src,dest);  // бисекция левой половины
      Result:=Result+Split(M+1,H,Src,dest); // бисекция правой половины
      Result:=Result+Merge(src,Dest,L,M,H);
      Src:=Dest;
    end;
  AR2:=Src;  {(*+*)}
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 SW:=0;
end;

procedure TForm1.Button1Click(Sender: TObject);
var i: integer;
begin
  randomize;
  for i:=1 to CHB do AR1[i]:=random(999);
  ShowVectorInList(ListBox1,AR1);
end;

procedure TForm1.ShowVectorInList(List:TListBox; Src:TSortArray);
var i:integer;
begin
 List.Items.Clear;
 for i:=1 to CHB do
 List.Items.Add(IntToStr(Src[i]));
end;

procedure TForm1.Button2Click(Sender: TObject);
var
SA: tSortArray;
begin
     SW:=0;
     SA:=AR1;
     SW:=Split(1,CHB,SA,SA);
     ShowVectorInList(ListBox2,AR2);
end;

procedure TForm1.Button3Click(Sender: TObject);
var
 i:integer;
 OldCursor:TCursor;
 k:real;
begin
 OldCursor:=Screen.Cursor;
 Screen.Cursor:=crHourGlass;
 for i:=1 to Form1.seElCount.Value do
 begin
  Application.ProcessMessages;
  seElCount.Value:=i; //устанавливаем длину сортируемого массива
  Button1.click; // генерируем массив случайным образом
  Button2.Click; //сортируем его
  k:=log(i,2);
  Series1.AddXY(i,i*k);
  Series2.AddXY(i,SW);
 end;
 Screen.Cursor:=OldCursor;
end;

end. 
volvo
А давай ты приведешь тот вариант, который (как ты утверждаешь) у тебя работает? Я например не вижу корректно работающей процедуры сортировки, а ползать по всей программе - это твоя проблема в первую очередь, раз уж ты ее так написал, что без этого не получается разобраться...
RussoTuristo
Функция Split производит расшепление последовательности символов, Merge сортирует, в принципе там еще комменты есть ... Могу их вынести отдельным сообщением ...
Есть программа моя, переделанная с индексами, но я там чето перемудрил ...и она вместо сортировки выводит одни нули ... задача уже мозг взрывает, вот важные процедуры из переделанной:

tIndexArray= array [1..1000] of integer;
function Merge(P:tIndexArray; src: TSortArray; var Dest:TSortArray; L,M,H: integer):integer;
//выполняет слияние 2-х половин массива src от L до M - нижняя,
//от M+1 до H - верхняя в массив Dest
var i,j,k: integer;
Begin
  Result:=0;
  i:=L;   // первый элемент последовательности
  j:=M+1; // первый элемент второй половины последовательности
  k:=L;   // место, куда записываем
  //пока не закончилась одна из половин
  while (i<=M)and(j<=H) do
  begin
    if src[P[i]]<src[P[j]] then   // после просмотра записываем i-й элемент
      begin
        Dest[k]:=P[i];
        inc(i);
        inc(Result); // перестановка!
      end
    else
    begin
      Dest[k]:=P[j];    // после просмотра записываем j-й элемент
      inc(j);
      inc(Result); // перестановка!
    end;
    inc(k);
  end;
  //записываем оставшиеся элементы
  if i>M then // дописываем правую половину
  while j<=H do
    begin
      Dest[k]:=P[j];
      inc(j); inc(k);
      inc(Result); // перестановка!
    end
  else
  while i<=M do
    begin      // дописываем левую половину
      Dest[k]:=P[i];
      inc(i); inc(k);
      inc(Result); // перестановка!
    end;
end;

{Процедура расщепления}
function Split(L,H: integer; var P: TIndexArray; var Dest: TSortArray):integer;
var M: integer;
Src:TSortArray;
// при первом обращении к данной процедуре массив Dest содержит копию src
Begin
  Result:=0;
  M:=(L+H) div 2; // середина последовательности
  // последовательность не элементарная => требуется разбиение
  If L<>H then
    begin
      Result:=Result+Split(L,M,P,dest);  // бисекция левой половины
      Result:=Result+Split(M+1,H,P,dest); // бисекция правой половины
      Result:=Result+Merge(P,Src,Dest,L,M,H);
      Src:=Dest;
    end;
  AR2:=Src;  {(*+*)}
end;
volvo
Что, издеваешься? Тебя просили НЕИНДЕКСНУЮ привести, РАБОТАЮЩУЮ!!! Нет, ты опять копируешь то, что и было в твоем архиве... Это я уже видел, зачем оно мне еще раз. Я хочу посмотреть на то, как БЕЗ ИНДЕКСОВ у тебя хоть что-то сортируется... Понимаешь? БЕЗ.
RussoTuristo
Извини, невнимательность ... ошибся и не ту прогу в архив сунул.
volvo
Раз - сами процедуры сортировки:
function Merge(var P:tIndexArray; src: TSortArray; var Dest:TSortArray; L,M,H: integer):integer;
var i,j,k: integer;
var DP: tindexarray;
Begin
  DP := P;
  Result:=0;
  i:=L;
  j:=M+1;
  k:=L;
  while (i<=M)and(j<=H) do begin
    if src[p[i]]<src[p[j]] then begin
      DP[k] := p[i];
      inc(i);
      inc(Result);
    end
    else begin
      dp[k] := p[j];
      inc(j);
      inc(Result);
    end;
    inc(k);
  end;

  if i>M then
    while j<=H do begin
      dp[k] := p[j];
      inc(j); inc(k);
      inc(Result);
    end
  else
    while i<=M do begin
      DP[k] := p[i];
      inc(i); inc(k);
      inc(Result);
    end;

  P := DP;
end;

function Split(var P: tIndexArray; L,H: integer; var src: TSortArray; var Dest: TSortArray):integer;
var M: integer;
Begin
  Result:=0;
  M:=(L+H) div 2;
  If L<>H then
    begin
      Result:=Result+Split(P, L,M,src,dest);
      Result:=Result+Split(P, M+1,H,Src,dest);
      Result:=Result+Merge(P, src,Dest,L,M,H);
    end;
  AR2:=Src;
end;
, два - вызов:
procedure TForm1.Button2Click(Sender: TObject);
var
  SA: tSortArray;
  P: tIndexArray;
  i: integer;
begin
     SW:=0;
     SA:=AR1;
     for i := 1 to CHB do P[i] := i; // Заполняем индексы значениями 1 .. CHB

     SW:=Split(P,1,CHB,SA,SA);

     ShowVectorInList(ListBox2,P); // Чтобы это отработало, я сделал tIndexArray = tSortArray;
end;
(в принципе, можно сделать другую процедуру для печати индексного массива).

Результат:
Нажмите для просмотра прикрепленного файла
, противоречия не вижу, индексы располагаются в правильном порядке...
RussoTuristo
Спасибо большое.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.