diff --git a/.gitignore b/.gitignore index 7297f31..f6cbc5f 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,7 @@ _book *.mobi *.pdf \.idea/ + +*.iml + +src/javaSortTest/target/ diff --git a/1.bubbleSort.md b/1.bubbleSort.md index e53a38d..621314f 100644 --- a/1.bubbleSort.md +++ b/1.bubbleSort.md @@ -77,3 +77,36 @@ func bubbleSort(arr []int) []int { return arr } ``` + +## 8. Java 代码实现 + +```java +public class BubbleSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + for (int i = 1; i < arr.length; i++) { + // 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。 + boolean flag = true; + + for (int j = 0; j < arr.length - i; j++) { + if (arr[j] > arr[j + 1]) { + int tmp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = tmp; + + flag = false; + } + } + + if (flag) { + break; + } + } + return arr; + } +} +``` diff --git a/10.radixSort.md b/10.radixSort.md index 5f40ea7..39b0a64 100644 --- a/10.radixSort.md +++ b/10.radixSort.md @@ -47,4 +47,89 @@ function radixSort(arr, maxDigit) { } return arr; } -``` \ No newline at end of file +``` + +## 4. Java 代码实现 + +```java +/** + * 基数排序 + * 考虑负数的情况还可以参考: https://code.i-harness.com/zh-CN/q/e98fa9 + */ +public class RadixSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + int maxDigit = getMaxDigit(arr); + return radixSort(arr, maxDigit); + } + + /** + * 获取最高位数 + */ + private int getMaxDigit(int[] arr) { + int maxValue = getMaxValue(arr); + return getNumLenght(maxValue); + } + + private int getMaxValue(int[] arr) { + int maxValue = arr[0]; + for (int value : arr) { + if (maxValue < value) { + maxValue = value; + } + } + return maxValue; + } + + protected int getNumLenght(long num) { + if (num == 0) { + return 1; + } + int lenght = 0; + for (long temp = num; temp != 0; temp /= 10) { + lenght++; + } + return lenght; + } + + private int[] radixSort(int[] arr, int maxDigit) { + int mod = 10; + int dev = 1; + + for (int i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) { + // 考虑负数的情况,这里扩展一倍队列数,其中 [0-9]对应负数,[10-19]对应正数 (bucket + 10) + int[][] counter = new int[mod * 2][0]; + + for (int j = 0; j < arr.length; j++) { + int bucket = ((arr[j] % mod) / dev) + mod; + counter[bucket] = arrayAppend(counter[bucket], arr[j]); + } + + int pos = 0; + for (int[] bucket : counter) { + for (int value : bucket) { + arr[pos++] = value; + } + } + } + + return arr; + } + + /** + * 自动扩容,并保存数据 + * + * @param arr + * @param value + */ + private int[] arrayAppend(int[] arr, int value) { + arr = Arrays.copyOf(arr, arr.length + 1); + arr[arr.length - 1] = value; + return arr; + } +} +``` diff --git a/2.selectionSort.md b/2.selectionSort.md index 6e3b3a4..ae7350f 100644 --- a/2.selectionSort.md +++ b/2.selectionSort.md @@ -71,3 +71,37 @@ func selectionSort(arr []int) []int { return arr } ``` + +## 6. Java 代码实现 + +```java +public class SelectionSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + // 总共要经过 N-1 轮比较 + for (int i = 0; i < arr.length - 1; i++) { + int min = i; + + // 每轮需要比较的次数 N-i + for (int j = i + 1; j < arr.length; j++) { + if (arr[j] < arr[min]) { + // 记录目前能找到的最小值元素的下标 + min = j; + } + } + + // 将找到的最小值和i位置所在的值进行交换 + if (i != min) { + int tmp = arr[i]; + arr[i] = arr[min]; + arr[min] = tmp; + } + + } + return arr; + } +} +``` diff --git a/3.insertionSort.md b/3.insertionSort.md index 11ed672..71beec9 100644 --- a/3.insertionSort.md +++ b/3.insertionSort.md @@ -65,3 +65,37 @@ func insertionSort(arr []int) []int { return arr } ``` + +## 6. Java 代码实现 + +```java +public class InsertSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的 + for (int i = 1; i < arr.length; i++) { + + // 记录要插入的数据 + int tmp = arr[i]; + + // 从已经排序的序列最右边的开始比较,找到比其小的数 + int j = i; + while (j > 0 && tmp < arr[j - 1]) { + arr[j] = arr[j - 1]; + j--; + } + + // 存在比其小的数,插入 + if (j != i) { + arr[j] = tmp; + } + + } + return arr; + } +} +``` diff --git a/4.shellSort.md b/4.shellSort.md index 0406030..c96d8b7 100644 --- a/4.shellSort.md +++ b/4.shellSort.md @@ -87,3 +87,36 @@ func shellSort(arr []int) []int { return arr } ``` + +## 5. Java 代码实现 + +```java +public class ShellSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + int gap = 1; + while (gap < arr.length) { + gap = gap * 3 + 1; + } + + while (gap > 0) { + for (int i = gap; i < arr.length; i++) { + int tmp = arr[i]; + int j = i - gap; + while (j >= 0 && arr[j] > tmp) { + arr[j + gap] = arr[j]; + j -= gap; + } + arr[j + gap] = tmp; + } + gap = (int) Math.floor(gap / 3); + } + + return arr; + } +} +``` diff --git a/5.mergeSort.md b/5.mergeSort.md index e1e1479..8394ab5 100644 --- a/5.mergeSort.md +++ b/5.mergeSort.md @@ -136,3 +136,53 @@ func merge(left []int, right []int) []int { return result } ``` + +## 7. Java 代码实现 + +```java +public class MergeSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + if (arr.length < 2) { + return arr; + } + int middle = (int) Math.floor(arr.length / 2); + + int[] left = Arrays.copyOfRange(arr, 0, middle); + int[] right = Arrays.copyOfRange(arr, middle, arr.length); + + return merge(sort(left), sort(right)); + } + + protected int[] merge(int[] left, int[] right) { + int[] result = new int[left.length + right.length]; + int i = 0; + while (left.length > 0 && right.length > 0) { + if (left[0] <= right[0]) { + result[i++] = left[0]; + left = Arrays.copyOfRange(left, 1, left.length); + } else { + result[i++] = right[0]; + right = Arrays.copyOfRange(right, 1, right.length); + } + } + + while (left.length > 0) { + result[i++] = left[0]; + left = Arrays.copyOfRange(left, 1, left.length); + } + + while (right.length > 0) { + result[i++] = right[0]; + right = Arrays.copyOfRange(right, 1, right.length); + } + + return result; + } + +} +``` diff --git a/6.quickSort.md b/6.quickSort.md index d08b28f..497f973 100644 --- a/6.quickSort.md +++ b/6.quickSort.md @@ -177,9 +177,54 @@ func swap(arr []int, i, j int) { void QuickSort(int A[], int low, int high) //快排母函数 { if (low < high) { - int pivot = Paritition1(A, low, high); + int pivot = Paritition1(A, low, high); QuickSort(A, low, pivot - 1); QuickSort(A, pivot + 1, high); } } ``` + +## 7. Java 代码实现 + +```java +public class QuickSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + return quickSort(arr, 0, arr.length - 1); + } + + private int[] quickSort(int[] arr, int left, int right) { + if (left < right) { + int partitionIndex = partition(arr, left, right); + quickSort(arr, left, partitionIndex - 1); + quickSort(arr, partitionIndex + 1, right); + } + return arr; + } + + private int partition(int[] arr, int left, int right) { + // 设定基准值(pivot) + int pivot = left; + int index = pivot + 1; + for (int i = index; i <= right; i++) { + if (arr[i] < arr[pivot]) { + swap(arr, i, index); + index++; + } + } + swap(arr, pivot, index - 1); + return index - 1; + } + + private void swap(int[] arr, int i, int j) { + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + +} +``` diff --git a/7.heapSort.md b/7.heapSort.md index d4bfa49..43d522c 100644 --- a/7.heapSort.md +++ b/7.heapSort.md @@ -147,3 +147,59 @@ func swap(arr []int, i, j int) { arr[i], arr[j] = arr[j], arr[i] } ``` + +## 6. Java 代码实现 + +```java +public class HeapSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + int len = arr.length; + + buildMaxHeap(arr, len); + + for (int i = len - 1; i > 0; i--) { + swap(arr, 0, i); + len--; + heapify(arr, 0, len); + } + return arr; + } + + private void buildMaxHeap(int[] arr, int len) { + for (int i = (int) Math.floor(len / 2); i >= 0; i--) { + heapify(arr, i, len); + } + } + + private void heapify(int[] arr, int i, int len) { + int left = 2 * i + 1; + int right = 2 * i + 2; + int largest = i; + + if (left < len && arr[left] > arr[largest]) { + largest = left; + } + + if (right < len && arr[right] > arr[largest]) { + largest = right; + } + + if (largest != i) { + swap(arr, i, largest); + heapify(arr, largest, len); + } + } + + private void swap(int[] arr, int i, int j) { + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + +} +``` diff --git a/8.countingSort.md b/8.countingSort.md index 164d3ac..b0f17e5 100644 --- a/8.countingSort.md +++ b/8.countingSort.md @@ -80,3 +80,49 @@ func countingSort(arr []int, maxValue int) []int { return arr } ``` + +## 5. Java 代码实现 + +```java +public class CountingSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + int maxValue = getMaxValue(arr); + + return countingSort(arr, maxValue); + } + + private int[] countingSort(int[] arr, int maxValue) { + int bucketLen = maxValue + 1; + int[] bucket = new int[bucketLen]; + + for (int value : arr) { + bucket[value]++; + } + + int sortedIndex = 0; + for (int j = 0; j < bucketLen; j++) { + while (bucket[j] > 0) { + arr[sortedIndex++] = j; + bucket[j]--; + } + } + return arr; + } + + private int getMaxValue(int[] arr) { + int maxValue = arr[0]; + for (int value : arr) { + if (maxValue < value) { + maxValue = value; + } + } + return maxValue; + } + +} +``` diff --git a/9.bucketSort.md b/9.bucketSort.md index 30966f4..e2e4aa6 100644 --- a/9.bucketSort.md +++ b/9.bucketSort.md @@ -61,4 +61,73 @@ function bucketSort(arr, bucketSize) { return arr; } -``` \ No newline at end of file +``` + +## 4. Java 代码实现 + +```java +public class BucketSort implements IArraySort { + + private static final InsertSort insertSort = new InsertSort(); + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + return bucketSort(arr, 5); + } + + private int[] bucketSort(int[] arr, int bucketSize) throws Exception { + if (arr.length == 0) { + return arr; + } + + int minValue = arr[0]; + int maxValue = arr[0]; + for (int value : arr) { + if (value < minValue) { + minValue = value; + } else if (value > maxValue) { + maxValue = value; + } + } + + int bucketCount = (int) Math.floor((maxValue - minValue) / bucketSize) + 1; + int[][] buckets = new int[bucketCount][0]; + + // 利用映射函数将数据分配到各个桶中 + for (int i = 0; i < arr.length; i++) { + int index = (int) Math.floor((arr[i] - minValue) / bucketSize); + buckets[index] = arrAppend(buckets[index], arr[i]); + } + + int arrIndex = 0; + for (int[] bucket : buckets) { + if (bucket.length <= 0) { + continue; + } + // 对每个桶进行排序,这里使用了插入排序 + bucket = insertSort.sort(bucket); + for (int value : bucket) { + arr[arrIndex++] = value; + } + } + + return arr; + } + + /** + * 自动扩容,并保存数据 + * + * @param arr + * @param value + */ + private int[] arrAppend(int[] arr, int value) { + arr = Arrays.copyOf(arr, arr.length + 1); + arr[arr.length - 1] = value; + return arr; + } + +} +``` diff --git a/src/java/main/BubbleSort.java b/src/java/main/BubbleSort.java new file mode 100644 index 0000000..3c8cebc --- /dev/null +++ b/src/java/main/BubbleSort.java @@ -0,0 +1,33 @@ +import java.util.Arrays; + +/** + * 冒泡排序 + */ +public class BubbleSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + for (int i = 1; i < arr.length; i++) { + // 设定一个标记,若为true,则表示此次循环没有进行交换,也就是待排序列已经有序,排序已经完成。 + boolean flag = true; + + for (int j = 0; j < arr.length - i; j++) { + if (arr[j] > arr[j + 1]) { + int tmp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = tmp; + + flag = false; + } + } + + if (flag) { + break; + } + } + return arr; + } +} diff --git a/src/java/main/BucketSort.java b/src/java/main/BucketSort.java new file mode 100644 index 0000000..c0b5183 --- /dev/null +++ b/src/java/main/BucketSort.java @@ -0,0 +1,69 @@ +import java.util.Arrays; + +/** + * 桶排序 + */ +public class BucketSort implements IArraySort { + + private static final InsertSort insertSort = new InsertSort(); + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + return bucketSort(arr, 5); + } + + private int[] bucketSort(int[] arr, int bucketSize) throws Exception { + if (arr.length == 0) { + return arr; + } + + int minValue = arr[0]; + int maxValue = arr[0]; + for (int value : arr) { + if (value < minValue) { + minValue = value; + } else if (value > maxValue) { + maxValue = value; + } + } + + int bucketCount = (int) Math.floor((maxValue - minValue) / bucketSize) + 1; + int[][] buckets = new int[bucketCount][0]; + + // 利用映射函数将数据分配到各个桶中 + for (int i = 0; i < arr.length; i++) { + int index = (int) Math.floor((arr[i] - minValue) / bucketSize); + buckets[index] = arrAppend(buckets[index], arr[i]); + } + + int arrIndex = 0; + for (int[] bucket : buckets) { + if (bucket.length <= 0) { + continue; + } + // 对每个桶进行排序,这里使用了插入排序 + bucket = insertSort.sort(bucket); + for (int value : bucket) { + arr[arrIndex++] = value; + } + } + + return arr; + } + + /** + * 自动扩容,并保存数据 + * + * @param arr + * @param value + */ + private int[] arrAppend(int[] arr, int value) { + arr = Arrays.copyOf(arr, arr.length + 1); + arr[arr.length - 1] = value; + return arr; + } + +} diff --git a/src/java/main/CountingSort.java b/src/java/main/CountingSort.java new file mode 100644 index 0000000..74fcd2a --- /dev/null +++ b/src/java/main/CountingSort.java @@ -0,0 +1,46 @@ +import java.util.Arrays; + +/** + * 计数排序 + */ +public class CountingSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + int maxValue = getMaxValue(arr); + + return countingSort(arr, maxValue); + } + + private int[] countingSort(int[] arr, int maxValue) { + int bucketLen = maxValue + 1; + int[] bucket = new int[bucketLen]; + + for (int value : arr) { + bucket[value]++; + } + + int sortedIndex = 0; + for (int j = 0; j < bucketLen; j++) { + while (bucket[j] > 0) { + arr[sortedIndex++] = j; + bucket[j]--; + } + } + return arr; + } + + private int getMaxValue(int[] arr) { + int maxValue = arr[0]; + for (int value : arr) { + if (maxValue < value) { + maxValue = value; + } + } + return maxValue; + } + +} diff --git a/src/java/main/HeapSort.java b/src/java/main/HeapSort.java new file mode 100644 index 0000000..6e9dcfe --- /dev/null +++ b/src/java/main/HeapSort.java @@ -0,0 +1,56 @@ +import java.util.Arrays; + +/** + * 堆排序 + */ +public class HeapSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + int len = arr.length; + + buildMaxHeap(arr, len); + + for (int i = len - 1; i > 0; i--) { + swap(arr, 0, i); + len--; + heapify(arr, 0, len); + } + return arr; + } + + private void buildMaxHeap(int[] arr, int len) { + for (int i = (int) Math.floor(len / 2); i >= 0; i--) { + heapify(arr, i, len); + } + } + + private void heapify(int[] arr, int i, int len) { + int left = 2 * i + 1; + int right = 2 * i + 2; + int largest = i; + + if (left < len && arr[left] > arr[largest]) { + largest = left; + } + + if (right < len && arr[right] > arr[largest]) { + largest = right; + } + + if (largest != i) { + swap(arr, i, largest); + heapify(arr, largest, len); + } + } + + private void swap(int[] arr, int i, int j) { + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + +} diff --git a/src/java/main/IArraySort.java b/src/java/main/IArraySort.java new file mode 100644 index 0000000..7d607e5 --- /dev/null +++ b/src/java/main/IArraySort.java @@ -0,0 +1,14 @@ +/** + * Created by corning on 2017/12/19. + */ +public interface IArraySort { + /** + * 对数组进行排序,并返回排序后的数组 + * + * @param sourceArray + * @return + * @throws Exception + */ + int[] sort(int[] sourceArray) throws Exception; + +} diff --git a/src/java/main/InsertSort.java b/src/java/main/InsertSort.java new file mode 100644 index 0000000..1321972 --- /dev/null +++ b/src/java/main/InsertSort.java @@ -0,0 +1,34 @@ +import java.util.Arrays; + +/** + * 插入排序 + */ +public class InsertSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + // 从下标为1的元素开始选择合适的位置插入,因为下标为0的只有一个元素,默认是有序的 + for (int i = 1; i < arr.length; i++) { + + // 记录要插入的数据 + int tmp = arr[i]; + + // 从已经排序的序列最右边的开始比较,找到比其小的数 + int j = i; + while (j > 0 && tmp < arr[j - 1]) { + arr[j] = arr[j - 1]; + j--; + } + + // 存在比其小的数,插入 + if (j != i) { + arr[j] = tmp; + } + + } + return arr; + } +} diff --git a/src/java/main/MergeSort.java b/src/java/main/MergeSort.java new file mode 100644 index 0000000..7fec2b8 --- /dev/null +++ b/src/java/main/MergeSort.java @@ -0,0 +1,50 @@ +import java.util.Arrays; + +/** + * 归并排序 + */ +public class MergeSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + if (arr.length < 2) { + return arr; + } + int middle = (int) Math.floor(arr.length / 2); + + int[] left = Arrays.copyOfRange(arr, 0, middle); + int[] right = Arrays.copyOfRange(arr, middle, arr.length); + + return merge(sort(left), sort(right)); + } + + protected int[] merge(int[] left, int[] right) { + int[] result = new int[left.length + right.length]; + int i = 0; + while (left.length > 0 && right.length > 0) { + if (left[0] <= right[0]) { + result[i++] = left[0]; + left = Arrays.copyOfRange(left, 1, left.length); + } else { + result[i++] = right[0]; + right = Arrays.copyOfRange(right, 1, right.length); + } + } + + while (left.length > 0) { + result[i++] = left[0]; + left = Arrays.copyOfRange(left, 1, left.length); + } + + while (right.length > 0) { + result[i++] = right[0]; + right = Arrays.copyOfRange(right, 1, right.length); + } + + return result; + } + +} diff --git a/src/java/main/QuickSort.java b/src/java/main/QuickSort.java new file mode 100644 index 0000000..1c598ed --- /dev/null +++ b/src/java/main/QuickSort.java @@ -0,0 +1,45 @@ +import java.util.Arrays; + +/** + * 快速排序 + */ +public class QuickSort implements IArraySort { + + @Override + public int[] sort(int[] sourceArray) throws Exception { + // 对 arr 进行拷贝,不改变参数内容 + int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); + + return quickSort(arr, 0, arr.length - 1); + } + + private int[] quickSort(int[] arr, int left, int right) { + if (left < right) { + int partitionIndex = partition(arr, left, right); + quickSort(arr, left, partitionIndex - 1); + quickSort(arr, partitionIndex + 1, right); + } + return arr; + } + + private int partition(int[] arr, int left, int right) { + // 设定基准值(pivot) + int pivot = left; + int index = pivot + 1; + for (int i = index; i <= right; i++) { + if (arr[i] < arr[pivot]) { + swap(arr, i, index); + index++; + } + } + swap(arr, pivot, index - 1); + return index - 1; + } + + private void swap(int[] arr, int i, int j) { + int temp = arr[i]; + arr[i] = arr[j]; + arr[j] = temp; + } + +} diff --git a/src/java/main/RadixSort.java b/src/java/main/RadixSort.java new file mode 100644 index 0000000..9052e76 --- /dev/null +++ b/src/java/main/RadixSort.java @@ -0,0 +1,83 @@ +import java.util.Arrays; + +/** + * 基数排序 + *
+ * 考虑负数的情况还可以参考: https://code.i-harness.com/zh-CN/q/e98fa9
+ */
+public class RadixSort implements IArraySort {
+
+ @Override
+ public int[] sort(int[] sourceArray) throws Exception {
+ // 对 arr 进行拷贝,不改变参数内容
+ int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
+
+ int maxDigit = getMaxDigit(arr);
+ return radixSort(arr, maxDigit);
+ }
+
+ /**
+ * 获取最高位数
+ */
+ private int getMaxDigit(int[] arr) {
+ int maxValue = getMaxValue(arr);
+ return getNumLenght(maxValue);
+ }
+
+ private int getMaxValue(int[] arr) {
+ int maxValue = arr[0];
+ for (int value : arr) {
+ if (maxValue < value) {
+ maxValue = value;
+ }
+ }
+ return maxValue;
+ }
+
+ protected int getNumLenght(long num) {
+ if (num == 0) {
+ return 1;
+ }
+ int lenght = 0;
+ for (long temp = num; temp != 0; temp /= 10) {
+ lenght++;
+ }
+ return lenght;
+ }
+
+ private int[] radixSort(int[] arr, int maxDigit) {
+ int mod = 10;
+ int dev = 1;
+
+ for (int i = 0; i < maxDigit; i++, dev *= 10, mod *= 10) {
+ // 考虑负数的情况,这里扩展一倍队列数,其中 [0-9]对应负数,[10-19]对应正数 (bucket + 10)
+ int[][] counter = new int[mod * 2][0];
+
+ for (int j = 0; j < arr.length; j++) {
+ int bucket = ((arr[j] % mod) / dev) + mod;
+ counter[bucket] = arrayAppend(counter[bucket], arr[j]);
+ }
+
+ int pos = 0;
+ for (int[] bucket : counter) {
+ for (int value : bucket) {
+ arr[pos++] = value;
+ }
+ }
+ }
+
+ return arr;
+ }
+
+ /**
+ * 自动扩容,并保存数据
+ *
+ * @param arr
+ * @param value
+ */
+ private int[] arrayAppend(int[] arr, int value) {
+ arr = Arrays.copyOf(arr, arr.length + 1);
+ arr[arr.length - 1] = value;
+ return arr;
+ }
+}
diff --git a/src/java/main/SelectionSort.java b/src/java/main/SelectionSort.java
new file mode 100644
index 0000000..0cee685
--- /dev/null
+++ b/src/java/main/SelectionSort.java
@@ -0,0 +1,34 @@
+import java.util.Arrays;
+
+/**
+ * 选择排序
+ */
+public class SelectionSort implements IArraySort {
+
+ @Override
+ public int[] sort(int[] sourceArray) throws Exception {
+ int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
+
+ // 总共要经过 N-1 轮比较
+ for (int i = 0; i < arr.length - 1; i++) {
+ int min = i;
+
+ // 每轮需要比较的次数 N-i
+ for (int j = i + 1; j < arr.length; j++) {
+ if (arr[j] < arr[min]) {
+ // 记录目前能找到的最小值元素的下标
+ min = j;
+ }
+ }
+
+ // 将找到的最小值和i位置所在的值进行交换
+ if (i != min) {
+ int tmp = arr[i];
+ arr[i] = arr[min];
+ arr[min] = tmp;
+ }
+
+ }
+ return arr;
+ }
+}
diff --git a/src/java/main/ShellSort.java b/src/java/main/ShellSort.java
new file mode 100644
index 0000000..6c0fbb1
--- /dev/null
+++ b/src/java/main/ShellSort.java
@@ -0,0 +1,33 @@
+import java.util.Arrays;
+
+/**
+ * 希尔排序
+ */
+public class ShellSort implements IArraySort {
+
+ @Override
+ public int[] sort(int[] sourceArray) throws Exception {
+ // 对 arr 进行拷贝,不改变参数内容
+ int[] arr = Arrays.copyOf(sourceArray, sourceArray.length);
+
+ int gap = 1;
+ while (gap < arr.length) {
+ gap = gap * 3 + 1;
+ }
+
+ while (gap > 0) {
+ for (int i = gap; i < arr.length; i++) {
+ int tmp = arr[i];
+ int j = i - gap;
+ while (j >= 0 && arr[j] > tmp) {
+ arr[j + gap] = arr[j];
+ j -= gap;
+ }
+ arr[j + gap] = tmp;
+ }
+ gap = (int) Math.floor(gap / 3);
+ }
+
+ return arr;
+ }
+}
diff --git a/src/java/pom.xml b/src/java/pom.xml
new file mode 100644
index 0000000..60b4858
--- /dev/null
+++ b/src/java/pom.xml
@@ -0,0 +1,70 @@
+
+