|
3 | 3 | import static com.thealgorithms.sorts.SortUtils.print; |
4 | 4 |
|
5 | 5 | import com.thealgorithms.datastructures.trees.BSTRecursiveGeneric; |
| 6 | +import java.util.ArrayList; |
| 7 | +import java.util.Arrays; |
6 | 8 | import java.util.List; |
7 | 9 |
|
8 | 10 | /** |
@@ -30,38 +32,39 @@ public <T extends Comparable<T>> List<T> sort(List<T> unsortedList) { |
30 | 32 | } |
31 | 33 |
|
32 | 34 | private <T extends Comparable<T>> T[] doTreeSortArray(T[] unsortedArray) { |
33 | | - // create a generic BST tree |
34 | | - BSTRecursiveGeneric<T> tree = new BSTRecursiveGeneric<T>(); |
35 | | - |
36 | | - // add all elements to the tree |
37 | | - for (T element : unsortedArray) { |
38 | | - tree.add(element); |
39 | | - } |
40 | | - |
41 | | - // get the sorted list by inorder traversal of the tree |
42 | | - List<T> sortedList = tree.inorderSort(); |
43 | | - |
44 | | - // add the elements back to the initial array |
45 | | - int i = 0; |
46 | | - for (T element : sortedList) { |
47 | | - unsortedArray[i++] = element; |
48 | | - } |
49 | | - |
50 | | - // return the array |
51 | | - return unsortedArray; |
| 35 | + // sort through the list path and copy the result back into the initial array |
| 36 | + List<T> sortedList = doTreeSortList(Arrays.asList(unsortedArray)); |
| 37 | + return sortedList.toArray(unsortedArray); |
52 | 38 | } |
53 | 39 |
|
54 | 40 | private <T extends Comparable<T>> List<T> doTreeSortList(Iterable<T> unsortedList) { |
55 | | - // create a generic BST tree |
56 | | - BSTRecursiveGeneric<T> tree = new BSTRecursiveGeneric<T>(); |
| 41 | + // the BST ignores duplicate keys, so pair every element with its position to keep equal values apart |
| 42 | + BSTRecursiveGeneric<Keyed<T>> tree = new BSTRecursiveGeneric<>(); |
57 | 43 |
|
58 | 44 | // add all elements to the tree |
| 45 | + int position = 0; |
59 | 46 | for (T element : unsortedList) { |
60 | | - tree.add(element); |
| 47 | + tree.add(new Keyed<>(element, position++)); |
61 | 48 | } |
62 | 49 |
|
63 | 50 | // get the sorted list by inorder traversal of the tree and return it |
64 | | - return tree.inorderSort(); |
| 51 | + List<T> sortedList = new ArrayList<>(); |
| 52 | + for (Keyed<T> keyed : tree.inorderSort()) { |
| 53 | + sortedList.add(keyed.value()); |
| 54 | + } |
| 55 | + return sortedList; |
| 56 | + } |
| 57 | + |
| 58 | + /** |
| 59 | + * An element plus its original position. Equal elements are ordered by position, |
| 60 | + * which also makes the sort stable. |
| 61 | + */ |
| 62 | + private record Keyed<T extends Comparable<T>>(T value, int position) implements Comparable<Keyed<T>> { |
| 63 | + @Override |
| 64 | + public int compareTo(Keyed<T> other) { |
| 65 | + int byValue = value.compareTo(other.value); |
| 66 | + return byValue != 0 ? byValue : Integer.compare(position, other.position); |
| 67 | + } |
65 | 68 | } |
66 | 69 |
|
67 | 70 | public static void main(String[] args) { |
|
0 commit comments