Recent

Author Topic: Merge Sort doesn't work if count of elements is very big  (Read 5591 times)

moskalenco_a

  • New Member
  • *
  • Posts: 19
Merge Sort doesn't work if count of elements is very big
« on: March 13, 2015, 03:33:10 pm »
Hi all! I have written code of Merge Sort.It works, but if count of elements above 50000 - RunTime Error,exitcode=201. It's maybe because of using too much memory. How can I solve this problem?
I tried to use dynamic arrays but that didn't help me.
Code: [Select]
type vector=array[1..1000000] of Integer;
var a:vector;

procedure merge(l,r,x,y:Integer);
var i,j,k,s:Integer;
c:vector;
begin
i:=l;
j:=y;
k:=1;
while (l<=r) and (x<=y) do
 begin

  if a[l]<a[x] then
   begin
    c[k]:=a[l];
    inc(l);
   end else
   begin
    c[k]:=a[x];
    inc(x);
   end;
  inc(k);

 end;

  if l<=r then
   for s:=l to r do
    begin
     c[k]:=a[s];
     inc(k);
    end else
   for s:=x to y do
    begin
     c[k]:=a[s];
     inc(k);
    end;

k:=1;
for s:=i to j do
 begin
  a[s]:=c[k];
  inc(k);
 end;
end;

procedure sort(const l,r:Integer);
var m:Integer;
begin
if l=r then Exit;
m:=(l+r) div 2;
sort(l,m);
sort(m+1,r);
merge(l,m,m+1,r);
end;

procedure create_rand_vect(var a:vector;const n:Integer);
var i:Integer;
begin
for i:=1 to n do a[i]:=Random(51)-25;
end;

procedure print_vector(const a:vector; const n:Integer);
var i:Integer;
begin
for i:=1 to n do Write(a[i],' ');
Writeln;
end;

var n:Integer;
begin
Write('n=');
Readln(n);
Randomize;
create_rand_vect(a,n);
Writeln('1:');
print_vector(a,n);
Writeln('2:');
sort(1,n);
print_vector(a,n);
Readln;
end.
P.S Sorry for my bad English, I'm from Ukraine...

Laksen

  • Hero Member
  • *****
  • Posts: 724
    • J-Software
Re: Merge Sort doesn't work if count of elements is very big
« Reply #1 on: March 13, 2015, 03:46:03 pm »
Try using longint instead of integer. Integer is 16 bit in Linux when compiling in mode FPC.

moskalenco_a

  • New Member
  • *
  • Posts: 19
Re: Merge Sort doesn't work if count of elements is very big
« Reply #2 on: March 13, 2015, 03:53:11 pm »
Thank you very much!!! There is even simplier solution: if write {$mode objfpc} Integer=LongInt and all is working!

moskalenco_a

  • New Member
  • *
  • Posts: 19
Re: Merge Sort doesn't work if count of elements is very big
« Reply #3 on: March 13, 2015, 04:03:38 pm »
And with dynamic arrays it's much more quckly!
Code: [Select]
{$mode objfpc}
type vector=array of Integer;
var a:vector;

procedure merge(l,r,x,y:Integer);
var i,j,k,s:Integer;
c:vector;
begin
i:=l;
j:=y;
k:=0;
SetLength(c,r-l+1+y-x+1);
while (l<=r) and (x<=y) do
 begin

  if a[l]<a[x] then
   begin
    c[k]:=a[l];
    inc(l);
   end else
   begin
    c[k]:=a[x];
    inc(x);
   end;
  inc(k);

 end;

  if l<=r then
   for s:=l to r do
    begin
     c[k]:=a[s];
     inc(k);
    end else
   for s:=x to y do
    begin
     c[k]:=a[s];
     inc(k);
    end;

k:=0;
for s:=i to j do
 begin
  a[s]:=c[k];
  inc(k);
 end;
end;

procedure sort(const l,r:Integer);
var m:Integer;
begin
if l=r then Exit;
m:=(l+r) div 2;
sort(l,m);
sort(m+1,r);
merge(l,m,m+1,r);
end;

procedure create_rand_vect(var a:vector;const n:Integer);
var i:Integer;
begin
SetLength(a,n);
for i:=0 to n-1 do a[i]:=Random(101);
end;

procedure print_vector(const a:vector; const n:Integer);
var i:Integer;
begin
for i:=0 to n-1 do Write(a[i],' ');
Writeln;
end;

var n:Integer;
begin
Write('n=');
Readln(n);
Randomize;
create_rand_vect(a,n);
{Writeln('1:');
print_vector(a,n);}
Writeln('2:');
sort(0,n-1);
print_vector(a,n);
Readln;
end.
Thank's for help!

djzepi

  • New Member
  • *
  • Posts: 36
Re: Merge Sort doesn't work if count of elements is very big
« Reply #4 on: March 14, 2015, 07:47:03 am »
Here is a small example that allows you to compare speeds

unit umergesort;

{$mode objfpc} {$H+}

interface

uses
  Classes, SysUtils;
type
   TItemMergeSort = integer;

procedure MergeSort( var a: array of TItemMergeSort );

implementation

procedure merge(var a: array of TItemMergeSort; l,r,x,y:Integer);
var
  i,j,k,s: Integer;
  c: array of TItemMergeSort;
begin
  i := l ;
  j := y ;
  k := 0 ;
  SetLength(c, r - l + 1 + y - x + 1 ) ;
  while (l <= r ) and ( x <= y ) do
   begin
      if a[ l ] < a[ x ] then
     begin
      c[ k ] := a[l ] ;
      inc( l ) ;
     end else
     begin
      c[ k ] := a[ x ] ;
      inc( x ) ;
     end;
    inc( k ) ;
   end;
    if l <= r then
     for s := l to r do
      begin
       c[k] := a[ s ] ;
       inc( k ) ;
      end else
     for s := x  to y do
      begin
       c[k] := a[ s ] ;
       inc( k ) ;
      end ;
  k := 0 ;
  for s := i to j do
   begin
    a[ s ] := c[ k ] ;
    inc( k ) ;
   end;
end;

procedure sort(var a: array of TItemMergeSort; const l,r:Integer);
var m:Integer;
begin
  if l=r then Exit;
  m:=(l+r) div 2;
  sort(a, l,m);
  sort(a, m+1,r);
  merge(a,l,m,m+1,r);
end;

procedure MergeSort( var a: array of TItemMergeSort );
var
  n : integer;
begin
  n := length( a );
  sort(a, 0, n-1 );
end;

end.


program mergesortcompare;


{$mode objfpc}

uses SysUtils,umergesort,UCountingSort;

type vector=array of Integer;
var a, b:vector;


procedure create_rand_vect(var a,b:vector;const n:Integer);
var i:Integer;
begin
  SetLength(a,n);
  SetLength(b,n);
  for i:=0 to n-1 do
    begin
      a:=Random(1010);
      b := a;
    end;
end;

procedure print_vector(const a:vector; const n:Integer);
var i:Integer;
begin
for i:=0 to n-1 do Write(a,' ');
Writeln;
end;

procedure copy_vect(var a,b:vector;const n:Integer);
var i:Integer;
begin
  for i:=0 to n-1 do
    begin
      b := a;
    end;
end;

var n:Integer;

  timeStart, timeEnd, timeTotal: TDateTime;
begin
  Write('n=');
  Readln(n);
  Randomize;
  create_rand_vect(a,b,n);
  {Writeln('1:');
  print_vector(a,n);}
  Writeln('2:');
  timeStart := now;
  CountingSort(b);
  timeEnd := now;
  timeTotal :=  timeEnd - timeStart ;
  Writeln('CountingSort:'+formatdatetime('hh:nn:ss:zzzz', timeTotal));
  copy_vect( a, b,n);
  timeStart := now;
  MergeSort( b );
  timeEnd := now;
  timeTotal :=  timeEnd - timeStart ;
  Writeln('MergeSort:'+formatdatetime('hh:nn:ss:zzzz', timeTotal));
  //print_vector(b,n);
  Readln;
end.     



unit UCountingSort can be found:

http://wiki.lazarus.freepascal.org/Counting_sort

Try the other alternatives

moskalenco_a

  • New Member
  • *
  • Posts: 19
Re: Merge Sort doesn't work if count of elements is very big
« Reply #5 on: March 14, 2015, 12:35:24 pm »
djzepi, thank's you! :)

 

TinyPortal © 2005-2018