I found several mergesort algorithms in the net and pasted together this one. it carries the indices along to keep the information where the element was before. but it turns out, that when i feed in an array which has the same value at each element the indices are shuffled. do i need to use another merge method?
procedure TMSortNode.MergeSort(values, indices: TMValueArrayPtr; L, R: Integer);
var
i, j, k, m : Integer;
begin
If (l < r) Then
begin
m:= (r+l) div 2;
MergeSort(values, indices, l, m );
MergeSort(values, indices, m+1, r );
For i:= l To m Do
begin
FValueBuffer[i]:= values^[i];
FIndexBuffer[i]:= indices^[i];
end;
i:= l;
For j:= m+1 To r Do
begin
FValueBuffer[r+m+1-j]:= values^[j];
FIndexBuffer[r+m+1-j]:= indices^[j];
end;
j:= r;
For k:= l To r Do
begin
If (FValueBuffer[i] <= FValueBuffer[j]) Then
begin
values^[k]:= FValueBuffer[i];
indices^[k]:= FIndexBuffer[i];
inc(i);
end
else
begin
values^[k]:= FValueBuffer[j];
indices^[k]:= FIndexBuffer[j];
dec(j);
end;
end;
end;
end;
EDIT:
this is the correct stable merge part:
length := r-l+1;
For i:= 0 To length-1 Do
begin
FValueBuffer[i]:= values^[l+i];
FIndexBuffer[i]:= indices^[l+i];
end;
j := 0;
k := m-l+1;
for i := 0 to length-1 do
if k < length then
begin
if j <= m-l then
begin
if FValueBuffer[j] > FValueBuffer[k] then begin
values^[l+i] := FValueBuffer[k];
indices^[l+i] := FIndexBuffer[k];
inc(k)
end else begin
values^[l+i] := FValueBuffer[j];
indices^[l+i] := FIndexBuffer[j];
inc(j);
end;
end
else
begin //only upper Entrys left
values^[i+l] := FValueBuffer[k];
indices^[i+l] := FIndexBuffer[k];
inc(k);
end;
end else begin //only superior Entrys left
values^[i+l] := FValueBuffer[j];
indices^[i+l] := FIndexBuffer[j];
inc(j);
end;