From 2c4e69eb243a81ba05d24456b3cad7e8a696f630 Mon Sep 17 00:00:00 2001 From: ajinkyakolhe112 Date: Wed, 10 Feb 2016 15:42:28 +0530 Subject: [PATCH] Using partition around pivot in quicksort for splitting arrays. Cleaner & Familiar code --- .../github/pedrovgs/problem8/SplitArray.java | 44 ++++++++++++++---- .../pedrovgs/problem8/SplitArrayTest.java | 46 +++++++++++++++++++ 2 files changed, 80 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/github/pedrovgs/problem8/SplitArray.java b/src/main/java/com/github/pedrovgs/problem8/SplitArray.java index dcdbfd75..9511ffc2 100644 --- a/src/main/java/com/github/pedrovgs/problem8/SplitArray.java +++ b/src/main/java/com/github/pedrovgs/problem8/SplitArray.java @@ -16,12 +16,11 @@ package com.github.pedrovgs.problem8; /** - * Given an array full of integers positive or negative write a method to move every negative - * number to the left and every positive number to the right. Take into account that the order of - * this elements into the array doesn't care. + * Given an array full of integers positive or negative write a method to move every negative number + * to the left and every positive number to the right. Take into account that the order of this + * elements into the array doesn't care. * - * Input: [1,2,3,-1-,2,-3] - * Output: [-2,-1,-3,2,3,1] + * Input: [1,2,3,-1-,2,-3] Output: [-2,-1,-3,2,3,1] * * @author Pedro Vicente Gómez Sánchez. */ @@ -56,9 +55,9 @@ public void splitSorting(int[] array) { /** * This solution for the problem is much faster than the previous one. Instead of use a sorting * algorithm we are going to go over the array from left to right using two pointers and swapping - * elements if needed. The complexity order of this algorithm in time terms is O(N) where N is - * the number of elements in the array. In space terms is O(1) because we are not using any - * additional data structure. + * elements if needed. The complexity order of this algorithm in time terms is O(N) where N is the + * number of elements in the array. In space terms is O(1) because we are not using any additional + * data structure. */ public void splitSwappingIterative(int[] array) { if (array == null) { @@ -84,12 +83,37 @@ public void splitSwappingIterative(int[] array) { } } + /** + * Using partition Method of quicksort to split array + */ + public void splitSwappingPartition(int[] array) { + if (array == null) { + throw new IllegalArgumentException("Array passed as parameter can't be null."); + } + + int left = 0; + int right = array.length - 1; + while (left < right) { + while (array[left] < 0 && left < right) { + left++; + } + while (array[right] >= 0 && left < right) { + right--; + } + if (left < right) { + swap(array, left, right); + left++; + right--; + } + } + } + /** * Tail recursive solution for this problem. This implementation has the same complexity order * O(N) and the only change is how we are going to iterate over the array, with the previous * implementation we are using a classic iterative approach and with this solution we are using - * recursion to iterate. In space terms is O(1) because we are not using any - * additional data structure. + * recursion to iterate. In space terms is O(1) because we are not using any additional data + * structure. */ public void splitSwappingRecursive(int[] array) { if (array == null) { diff --git a/src/test/java/com/github/pedrovgs/problem8/SplitArrayTest.java b/src/test/java/com/github/pedrovgs/problem8/SplitArrayTest.java index 59ac0a8b..fc2f56fd 100644 --- a/src/test/java/com/github/pedrovgs/problem8/SplitArrayTest.java +++ b/src/test/java/com/github/pedrovgs/problem8/SplitArrayTest.java @@ -120,6 +120,52 @@ public void shouldMoveNegativeElementsToTheLeftWithWithMoreNegativeElementsTwoPo assertNegativeElementsAreBeforePositiveOnes(array); } + @Test(expected = IllegalArgumentException.class) + public void shouldNotAcceptNullArraysWithPartition() { + splitArray.splitSwappingPartition(null); + } + + @Test public void shouldSupportEmptyArraysWithPartition() { + int[] array = new int[0]; + + splitArray.splitSwappingPartition(array); + + assertNegativeElementsAreBeforePositiveOnes(array); + } + + @Test public void shouldWorkWithAnArrayFullOfPositiveNumbersWithPartition() { + int[] array = { 1, 2, 1, 3, 4, 6 }; + + splitArray.splitSwappingPartition(array); + + assertNegativeElementsAreBeforePositiveOnes(array); + } + + @Test public void shouldWorkWithAnArrayFullOfNegativeNumbersWithPartition() { + int[] array = { 1, 2, 1, 3, 4, 6 }; + + splitArray.splitSwappingPartition(array); + + assertNegativeElementsAreBeforePositiveOnes(array); + } + + @Test public void shouldMoveNegativeElementsToTheLeftWithPartition() { + int[] array = { 1, 2, -1, -3, 4, -6 }; + + splitArray.splitSwappingPartition(array); + + assertNegativeElementsAreBeforePositiveOnes(array); + } + + @Test + public void shouldMoveNegativeElementsToTheLeftWithWithMoreNegativeElementsWithPartition() { + int[] array = { 1, -2, -1, -3, 4, -6 }; + + splitArray.splitSwappingPartition(array); + + assertNegativeElementsAreBeforePositiveOnes(array); + } + @Test(expected = IllegalArgumentException.class) public void shouldNotAcceptNullArraysWithTwoPointersRecursive() {