Skip to content

Commit e4046a4

Browse files
authored
Add Insertion Sort in Pascal (TheRenegadeCoder#4833)
1 parent 25178d7 commit e4046a4

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
program InsertionSort;
2+
3+
{$mode objfpc}{$H+}
4+
5+
uses
6+
Classes,
7+
Generics.Collections,
8+
StrUtils,
9+
SysUtils;
10+
11+
type
12+
TIntegerList = specialize TList<integer>;
13+
14+
procedure ShowUsage;
15+
begin
16+
Writeln('Usage: please provide a list of at least two integers to sort in the format "1, 2, 3, 4, 5"');
17+
Halt(1);
18+
end;
19+
20+
function ParseIntegerList(const S: string): TIntegerList;
21+
var
22+
Tokens: TStringArray;
23+
Token: string;
24+
Value: integer;
25+
begin
26+
if S.Trim = '' then
27+
ShowUsage;
28+
29+
Tokens := S.Split([',']);
30+
if Length(Tokens) < 2 then
31+
ShowUsage;
32+
33+
Result := TIntegerList.Create;
34+
for Token in Tokens do
35+
begin
36+
if not TryStrToInt(Trim(Token), Value) then
37+
begin
38+
Result.Free;
39+
ShowUsage;
40+
end;
41+
Result.Add(Value);
42+
end;
43+
end;
44+
45+
function FormatIntegerList(const List: TIntegerList): string;
46+
var
47+
i: integer;
48+
begin
49+
Result := '';
50+
for i := 0 to List.Count - 1 do
51+
begin
52+
if i > 0 then
53+
Result += ', ';
54+
Result += IntToStr(List[i]);
55+
end;
56+
end;
57+
58+
procedure InsertionSort(List: TIntegerList);
59+
var
60+
i, j, key, insertPos: integer;
61+
AlreadySorted: boolean;
62+
63+
// This is an optional optimization on insertion sort, reducing the number of
64+
// comparisons needed. Essentially, we're using binary search to find the
65+
// appropiate position. Binary search is O(log n), so the number of
66+
// comparisons will be O(n log n) as opposed to O(n²). The time complexity
67+
// is still O(n²).
68+
function FindInsertPosition(const Key: integer; HighBound: integer): integer;
69+
var
70+
Low, High, Mid: integer;
71+
begin
72+
Low := 0;
73+
High := HighBound - 1; // search only within sorted portion (0..i-1)
74+
75+
while Low <= High do
76+
begin
77+
Mid := Low + (High - Low) shr 1;
78+
if List[Mid] < Key then
79+
Low := Mid + 1
80+
else
81+
High := Mid - 1;
82+
end;
83+
84+
Result := Low;
85+
end;
86+
87+
begin
88+
if List.Count <= 1 then
89+
Exit;
90+
91+
for i := 1 to List.Count - 1 do
92+
begin
93+
key := List[i];
94+
95+
// Optimization: skip if key is already greater or equal to previous element
96+
if key >= List[i - 1] then
97+
Continue;
98+
99+
// Find insertion position in sorted subarray [0..i-1]
100+
insertPos := FindInsertPosition(key, i);
101+
102+
// Shift elements to the right to make room for key
103+
j := i;
104+
while j > insertPos do
105+
begin
106+
List[j] := List[j - 1];
107+
Dec(j);
108+
end;
109+
110+
List[insertPos] := key;
111+
end;
112+
end;
113+
114+
var
115+
rawArg: string;
116+
numbers: TIntegerList;
117+
begin
118+
if ParamCount <> 1 then
119+
ShowUsage;
120+
121+
rawArg := ParamStr(1);
122+
numbers := ParseIntegerList(rawArg);
123+
try
124+
InsertionSort(numbers);
125+
Writeln(FormatIntegerList(numbers));
126+
finally
127+
numbers.Free;
128+
end;
129+
end.

0 commit comments

Comments
 (0)