From d4af68bd865cffa3a3c41305f1a165bcaf3c9b25 Mon Sep 17 00:00:00 2001 From: Lars Kotthoff Date: Wed, 15 Aug 2018 17:32:45 -0600 Subject: [PATCH 1/2] choose pivot from median of three elements for quicksort --- src/algorithms/sorting/quick-sort/QuickSort.js | 16 ++++++++++++---- .../quick-sort/__test__/QuickSort.test.js | 8 ++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/algorithms/sorting/quick-sort/QuickSort.js b/src/algorithms/sorting/quick-sort/QuickSort.js index 1c63c86e..c1d14332 100644 --- a/src/algorithms/sorting/quick-sort/QuickSort.js +++ b/src/algorithms/sorting/quick-sort/QuickSort.js @@ -14,13 +14,21 @@ export default class QuickSort extends Sort { return array; } - // Init left and right arrays. + // Init left, center, and right arrays. const leftArray = []; const rightArray = []; + const centerArray = []; - // Take the first element of array as a pivot. - const pivotElement = array.shift(); - const centerArray = [pivotElement]; + // Take the median element of first, mid, and last elements. + let pivotElement = array[0]; + const mid = Math.floor(array.length / 2); + if ((array[mid] < array[array.length - 1] && array[mid] > array[0]) + || (array[mid] > array[array.length - 1] && array[mid] < array[0])) { + pivotElement = array[mid]; + } else if ((array[array.length - 1] < array[mid] && array[array.length - 1] > array[0]) + || (array[array.length - 1] > array[mid] && array[array.length - 1] < array[0])) { + pivotElement = array[array.length - 1]; + } // Split all array elements between left, center and right arrays. while (array.length) { diff --git a/src/algorithms/sorting/quick-sort/__test__/QuickSort.test.js b/src/algorithms/sorting/quick-sort/__test__/QuickSort.test.js index 71c1fe71..52157716 100644 --- a/src/algorithms/sorting/quick-sort/__test__/QuickSort.test.js +++ b/src/algorithms/sorting/quick-sort/__test__/QuickSort.test.js @@ -8,10 +8,10 @@ import { } from '../../SortTester'; // Complexity constants. -const SORTED_ARRAY_VISITING_COUNT = 190; -const NOT_SORTED_ARRAY_VISITING_COUNT = 62; -const REVERSE_SORTED_ARRAY_VISITING_COUNT = 190; -const EQUAL_ARRAY_VISITING_COUNT = 19; +const SORTED_ARRAY_VISITING_COUNT = 66; +const NOT_SORTED_ARRAY_VISITING_COUNT = 83; +const REVERSE_SORTED_ARRAY_VISITING_COUNT = 66; +const EQUAL_ARRAY_VISITING_COUNT = 20; describe('QuickSort', () => { it('should sort array', () => { From 478abbadc93b7a494f7c1f039bee265d372479e0 Mon Sep 17 00:00:00 2001 From: Lars Kotthoff Date: Tue, 11 Dec 2018 10:49:49 -0700 Subject: [PATCH 2/2] fix pivot picking and kruskal's algorithm --- src/algorithms/graph/kruskal/kruskal.js | 2 +- src/algorithms/sorting/quick-sort/QuickSort.js | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/algorithms/graph/kruskal/kruskal.js b/src/algorithms/graph/kruskal/kruskal.js index dd9968a0..3c44a2ad 100644 --- a/src/algorithms/graph/kruskal/kruskal.js +++ b/src/algorithms/graph/kruskal/kruskal.js @@ -24,7 +24,7 @@ export default function kruskal(graph) { */ compareCallback: (graphEdgeA, graphEdgeB) => { if (graphEdgeA.weight === graphEdgeB.weight) { - return 1; + return 0; } return graphEdgeA.weight <= graphEdgeB.weight ? -1 : 1; diff --git a/src/algorithms/sorting/quick-sort/QuickSort.js b/src/algorithms/sorting/quick-sort/QuickSort.js index c1d14332..c3c94361 100644 --- a/src/algorithms/sorting/quick-sort/QuickSort.js +++ b/src/algorithms/sorting/quick-sort/QuickSort.js @@ -22,11 +22,15 @@ export default class QuickSort extends Sort { // Take the median element of first, mid, and last elements. let pivotElement = array[0]; const mid = Math.floor(array.length / 2); - if ((array[mid] < array[array.length - 1] && array[mid] > array[0]) - || (array[mid] > array[array.length - 1] && array[mid] < array[0])) { + if ((this.comparator.lessThan(array[mid], array[array.length - 1]) + && this.comparator.greaterThan(array[mid], array[0])) + || (this.comparator.greaterThan(array[mid], array[array.length - 1]) + && this.comparator.lessThan(array[mid], array[0]))) { pivotElement = array[mid]; - } else if ((array[array.length - 1] < array[mid] && array[array.length - 1] > array[0]) - || (array[array.length - 1] > array[mid] && array[array.length - 1] < array[0])) { + } else if ((this.comparator.lessThan(array[array.length - 1], array[mid]) + && this.comparator.greaterThan(array[array.length - 1], array[0])) + || (this.comparator.greaterThan(array[array.length - 1], array[mid]) + && this.comparator.lessThan(array[array.length - 1], array[0]))) { pivotElement = array[array.length - 1]; }