diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b62d5f3..ef1f0c8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,6 +43,7 @@ Every project is managed by the `build.zig` file. ├── sort │ ├── bubbleSort.zig │ ├── insertionSort.zig +│ ├── selectionSort.zig │ ├── mergeSort.zig │ ├── quickSort.zig │ └── radixSort.zig diff --git a/build.zig b/build.zig index d5a7551..05fec6b 100644 --- a/build.zig +++ b/build.zig @@ -42,6 +42,13 @@ pub fn build(b: *std.Build) void { .name = "insertionSort.zig", .category = "sort", }); + if (std.mem.eql(u8, op, "sort/selectionSort")) + buildAlgorithm(b, .{ + .optimize = optimize, + .target = target, + .name = "selectionSort.zig", + .category = "sort", + }); // Search algorithms if (std.mem.eql(u8, op, "search/bSearchTree")) diff --git a/runall.zig b/runall.zig index d107baa..91dea66 100644 --- a/runall.zig +++ b/runall.zig @@ -33,6 +33,7 @@ pub fn main() !void { try runTest(allocator, "sort/radixsort"); try runTest(allocator, "sort/mergesort"); try runTest(allocator, "sort/insertsort"); + try runTest(allocator, "sort/selectionSort"); // Search try runTest(allocator, "search/bSearchTree"); diff --git a/sort/selectionSort.zig b/sort/selectionSort.zig new file mode 100644 index 0000000..a0e86d7 --- /dev/null +++ b/sort/selectionSort.zig @@ -0,0 +1,93 @@ +const std = @import("std"); +const mem = std.mem; +const expect = std.testing.expect; + +// Reference: https://www.geeksforgeeks.org/dsa/selection-sort-algorithm-2/ +fn sort(A: []i64) void { + for (0..A.len) |i| { + var smallest: usize = i; + + for (i + 1..A.len) |j| { + // condetion: < for ascending order and > for descending order + if (A[j] < A[smallest]) { + smallest = j; + } + } + + mem.swap(i64, &A[i], &A[smallest]); + } +} + +test "empty array" { + var A = [_]i64{}; + sort(&A); + for (A, 0..) |value, i| { + try expect(value == i); + } +} + +test "single element" { + var A = [_]i64{0}; + sort(&A); + for (A, 0..) |value, i| { + try expect(value == i); + } +} + +test "reverse order" { + var A = [_]i64{ 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + sort(&A); + for (A, 0..) |value, i| { + try expect(value == i); + } +} + +test "all same" { + var A = [_]i64{ 0, 0, 0, 0, 0, 0 }; + const forTest = [_]i64{ 0, 0, 0, 0, 0, 0 }; + sort(&A); + for (A, forTest) |i, j| { + try expect(i == j); + } +} + +test "sorted" { + var A = [_]i64{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + sort(&A); + for (A, 0..) |value, i| { + try expect(value == i); + } +} + +test "partially sorted" { + var A = [_]i64{ 0, 1, 2, 3, 4, 9, 6, 5, 8, 7 }; + sort(&A); + for (A, 0..) |value, i| { + try expect(value == i); + } +} + +test "last two unordered" { + var A = [_]i64{ 0, 1, 2, 3, 4, 5, 6, 7, 9, 8 }; + sort(&A); + for (A, 0..) |value, i| { + try expect(value == i); + } +} + +test "first two unordered" { + var A = [_]i64{ 1, 0, 2, 3, 4, 5, 6, 7, 8, 9 }; + sort(&A); + for (A, 0..) |value, i| { + try expect(value == i); + } +} + +test "negative numbers with duplicates" { + var A = [_]i64{ -6, -3, 6, 0, -7, 2, 1, 8, -5, 1, 6 }; + const sortedA = [_]i64{ -7, -6, -5, -3, 0, 1, 1, 2, 6, 6, 8 }; + sort(&A); + for (A, sortedA) |i, j| { + try expect(i == j); + } +}