Browse Source

AK: Fix InsertionSort to respect specified bounds

Previously, it ignored 'start', sorting from the array's
beginning. This caused unintended changes and slower
performance. Fix ensures sorting stays within 'start'
and 'end' indices only.
Pavel Shliak 7 months ago
parent
commit
c16c20b836
2 changed files with 24 additions and 1 deletions
  1. 1 1
      AK/InsertionSort.h
  2. 23 0
      Tests/AK/TestInsertionSort.cpp

+ 1 - 1
AK/InsertionSort.h

@@ -17,7 +17,7 @@ void insertion_sort(Collection& col, ssize_t start, ssize_t end, Comparator comp
 requires(Indexable<Collection, T>)
 requires(Indexable<Collection, T>)
 {
 {
     for (ssize_t i = start + 1; i <= end; ++i) {
     for (ssize_t i = start + 1; i <= end; ++i) {
-        for (ssize_t j = i; j > 0 && comparator(col[j], col[j - 1]); --j)
+        for (ssize_t j = i; j > start && comparator(col[j], col[j - 1]); --j)
             swap(col[j], col[j - 1]);
             swap(col[j], col[j - 1]);
     }
     }
 }
 }

+ 23 - 0
Tests/AK/TestInsertionSort.cpp

@@ -55,3 +55,26 @@ TEST_CASE(sorts_decending)
         }
         }
     }
     }
 }
 }
+
+TEST_CASE(sorts_subrange_without_affecting_outside_elements)
+{
+    Vector<int> ints = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 };
+    Vector<int> const original_ints = ints;
+
+    ssize_t const start = 3;
+    ssize_t const end = 6;
+
+    insertion_sort(ints, start, end, [](auto& a, auto& b) { return a < b; });
+
+    for (ssize_t i = start; i < end; ++i) {
+        EXPECT(ints[i] <= ints[i + 1]);
+    }
+
+    for (ssize_t i = 0; i < start; ++i) {
+        EXPECT_EQ(ints[i], original_ints[i]);
+    }
+
+    for (ssize_t i = end + 1; i < static_cast<ssize_t>(ints.size()); ++i) {
+        EXPECT_EQ(ints[i], original_ints[i]);
+    }
+}