update isSorted after shuffling

A list can be sorted after shuffling. The trivial cases are
the empty list and a list with only one element or lists 
with only identical elements. Lists with only a few elements 
have a non-negligible chance to be sorted after shuffling.
This commit is contained in:
2017-12-18 20:10:27 +01:00
parent 297ab6fd40
commit 45dd73d8f3
2 changed files with 50 additions and 1 deletions

View File

@@ -556,7 +556,12 @@ public final class IntList implements Serializable, Cloneable {
data[other] = data[i];
data[i] = tmp;
}
sorted = false;
// update sorted
sorted = true;
for (int i = 1; i < size && sorted; i++) {
sorted = data[i - 1] <= data[i];
}
}
private void ensureCapacity(final int newElements) {

View File

@@ -600,6 +600,50 @@ public class IntListTest {
Assert.assertTrue("shuffled list minus original: " + list, list.isEmpty());
}
@Test
public void testShuffle_sortOfEmptyElementList() {
final IntList list = IntList.of();
list.shuffle();
Assert.assertTrue("an empty list is sorted", list.isSorted());
}
@Test
public void testShuffle_sortOfOneElementList() {
final IntList list = IntList.of(1);
list.shuffle();
Assert.assertTrue("a shuffled list of size 1 is sorted", list.isSorted());
}
@Test
public void testShuffle_sortOfListWithIdenticalElements() {
final IntList list = IntList.of(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1);
list.shuffle();
Assert.assertTrue("a shuffled list with identical elements is sorted", list.isSorted());
}
@Test
public void testShuffle_sortOfThreeElementList() {
final IntList list = IntList.of(2, 3, 1);
int sorted = 0;
int unsorted = 0;
for (int i = 0; i < 20; i++) {
final Random random = new Random(i);
list.shuffle(random);
sorted += IntList.of(1, 2, 3).equals(list) ? 1 : 0;
unsorted += IntList.of(1, 2, 3).equals(list) ? 0 : 1;
Assert.assertEquals(IntList.of(1, 2, 3).equals(list), list.isSorted());
}
Assert.assertTrue(sorted > 0);
Assert.assertTrue(unsorted > 0);
}
private int[] removeElements(final int[] data, final int... removedIndices) {
final int[] result = new int[data.length - removedIndices.length];
final List<Integer> blacklist = Arrays.stream(removedIndices).boxed().collect(Collectors.toList());