All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.andyshao.arithmetic.ArraySort Maven / Gradle / Ivy

The newest version!
package com.github.andyshao.arithmetic;

import com.github.andyshao.lang.ArrayWrapper;
import com.github.andyshao.lang.Convert;

import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Random;

/**
 * 
 * Title:
* Descript:
* Copyright: Copryright(c) Feb 28, 2015
* Encoding:UNIX UTF-8 * * @author Andy.Shao * */ public final class ArraySort { /** * count sort(计数排序)
* 速度比快速排序快,但是占用空间巨大.稳定的排序能使具有相同 * 数值的元素有相同的顺序. * * @param array array * @param convert calculate the data to a integer * @param start start position(inclusive) * @param end end position(exclusive) * @param max the max value(k) of array clip which from start side to end * side but never * include the end side. the max = k + 1 * @param data type * @param array type * @return the array which has been sorted. * @throws IllegalArgumentException if start bigger than or equal end. */ @SuppressWarnings("unchecked") public static final ARRAY ctsort(ARRAY array , Convert convert , int start , int end , int max) { final ArrayWrapper arrayWrapper = ArrayWrapper.wrap(array); return (ARRAY) ArraySort.ctsort(arrayWrapper , convert , start , end , max).array(); } /** * count sort * @param array the array which should be sorted * @param convert calculate the data to a integer * @param start start position (include) * @param end end position (exclude) * @param max the max value(k) of array clip which from start side to end * side but never include the end side. * the max = k + 1 * @return the array which has been sorted * @param data type */ @SuppressWarnings("unchecked") public static final ArrayWrapper ctsort(ArrayWrapper array , Convert convert , int start , int end , int max) { if (start > end) throw new IllegalArgumentException(start + " bigger than or equal " + end); int[] counts = new int[max]; Arrays.fill(counts , 0); //Count the occurrences of each element. for (int i = start ; i < end ; i++) { Integer index = convert.convert((DATA) array.get(i)); counts[index] = counts[index] + 1; } //Adjust each count to reflect the counts before it. for (int i = 1 ; i < max ; i++) counts[i] = counts[i] + counts[i - 1]; Object temp = Array.newInstance(array.array().getClass().getComponentType() , array.length()); ArrayWrapper tempWrapper = ArrayWrapper.wrap(temp); //Use the counts to position each element where it belongs. for (int i = end - 1 ; i >= start ; i--) { int index = convert.convert((DATA) array.get(i)); tempWrapper.put(array.get(i) , counts[index] - 1 + start); counts[index] = counts[index] - 1; } //Prepare to pass back the sorted data. System.arraycopy(temp , start , array.array() , start , end - start); return array; } /** * insert sort(插入排序) * * @param data array * @param comparator {@link Comparator} * @param start start position(inclusive) * @param end end position(exclusive) * @param array type * @param data type * @return if the data is null then return it. * @throws IllegalArgumentException if start bigger than or equal end */ @SuppressWarnings("unchecked") public static final ARRAY issort(final ARRAY data , int start , int end , Comparator comparator) { final ArrayWrapper arrayWrapper = ArrayWrapper.wrap(data); return (ARRAY) ArraySort.issort(arrayWrapper , start , end , comparator).array(); } /** * insert sort * @param data a unordered array * @param start the start position (include) * @param end the end position (exclude) * @param comparator {@link Comparator} * @return if the data is null then return it * @param data type */ @SuppressWarnings("unchecked") public static final ArrayWrapper issort(final ArrayWrapper data , int start , int end , Comparator comparator) { if (start > end) throw new IllegalArgumentException(start + " bigger than or equal " + end); //Repeatedly insert a key element among the sorted elements. for (int i = start + 1 ; i < end ; i++) { DATA temp = (DATA) data.get(i); int j = i - 1; //Determine the position at which to insert the key element. for (; j >= start && comparator.compare((DATA) data.get(j) , temp) > 0 ; j--) data.put(data.get(j) , j + 1); data.put(temp , j + 1); } return data; } /** * merge sort * @param array a unordered array * @param start the start position (include) * @param division the divided position * @param end the end position (exclude) * @param comparator {@link Comparator} * @return an ordered array * @param data type */ @SuppressWarnings("unchecked") static final ArrayWrapper merge(ArrayWrapper array , int start , int division , int end , Comparator comparator) { //initialize the counters used in merging. int leftPos = start; int rightPos = division + 1; int tempPos = 0; Object temp = Array.newInstance(array.array().getClass().getComponentType() , end - start); ArrayWrapper tempWrapper = ArrayWrapper.wrap(temp); //Continue while either division has elements to merge. FIRST: while (leftPos <= division || rightPos < end) { if (leftPos > division) { //The left division has no more elements to merge. while (rightPos < end) tempWrapper.put(array.get(rightPos++) , tempPos++); continue FIRST; } else if (rightPos >= end) { //The right division has no more elements to merge. while (leftPos <= division) tempWrapper.put(array.get(leftPos++) , tempPos++); continue FIRST; } //Append the next ordered element to the merged elements. if (comparator.compare((DATA) array.get(leftPos) , (DATA) array.get(rightPos)) < 0) tempWrapper.put(array.get(leftPos++) , tempPos++); else tempWrapper.put(array.get(rightPos++) , tempPos++); } //Prepare to pass back the merged data. System.arraycopy(temp , 0 , array.array() , start , end - start); return array; } /** * Merge sort(归并排序)
* 归并排序在所有情况下都能达到快速排序的平均性能.必须要有两倍于无序数据集 * 的空间来运行算法. * * @param data array which should be sorted * @param start start position(inclusive) * @param end end position(exclusive) * @param comparator {@link Comparator} * @param data type * @param array type * @return the array which has been sorted * @throws IllegalArgumentException if start bigger than or equal end */ @SuppressWarnings("unchecked") public static final ARRAY mgsort(ARRAY data , int start , int end , Comparator comparator) { final ArrayWrapper arrayWrapper = ArrayWrapper.wrap(data); return (ARRAY) ArraySort.mgsort(arrayWrapper , start , end , comparator).array(); } /** * Merge sort * @param data a unordered array * @param start the start position * @param end the end position * @param comparator {@link Comparator} * @return a ordered array * @param the data type */ public static final ArrayWrapper mgsort(ArrayWrapper data , int start , int end , Comparator comparator) { if (start > end) throw new IllegalArgumentException(start + " bigger than or equal " + end); //Stop the recursion when no more divisions can be made. if (start < end - 1) { int division; //Determine where to divide the elements. division = (start + end) / 2; //Recursively sort the two divisions. ArraySort.mgsort(data , start , division , comparator); ArraySort.mgsort(data , division , end , comparator); //Merge the two sorted divisions into a single sorted set. ArraySort.merge(data , start , division - 1 , end , comparator); } return data; } @SuppressWarnings("unchecked") static final int partition(ArrayWrapper array , int start , int end , Comparator comparator) { int[] r = new int[3]; final Random random = new Random(); int tail = end - 1; //Use the median-of-three method to find the partition value. r[0] = random.ints(start , tail).findFirst().getAsInt(); r[1] = random.ints(start , tail).findFirst().getAsInt(); r[2] = random.ints(start , tail).findFirst().getAsInt(); ArraySort. issort(r , 0 , r.length , (i1 , i2) -> Integer.compare(i1 , i2)); DATA pval = (DATA) array.get(r[1]); //Create two partitions around the partition value. start--; tail++; while (true) { //Move left until an element is found in the wrong partition. do tail--; while (comparator.compare((DATA) array.get(tail) , pval) > 0); //Move right until an element is found in the wrong partition. do start++; while (comparator.compare((DATA) array.get(start) , pval) < 0); if (start >= tail) //Stop partitioning when the left and right counters cross. break; else { //Swap the elements now under the left and right counters. DATA temp = (DATA) array.get(start); array.put(array.get(tail) , start); array.put(temp , tail); } } return tail; } /** * quick sort(快速排序) * * @param array array * @param start the begin of sort(inclusive) * @param end the end of sort(exclusive) * @param comparator {@link Comparator} * @param data type * @param array type * @return the array which is sorted. * @throws SortException when the sort has error. * @throws IllegalArgumentException if start bigger than or equal end */ @SuppressWarnings("unchecked") public static final ARRAY qksort(final ARRAY array , int start , int end , Comparator comparator) { final ArrayWrapper arrayWrapper = ArrayWrapper.wrap(array); return (ARRAY) ArraySort.qksort(arrayWrapper , start , end , comparator).array(); } /** * quick sort * @param array a unordered array * @param start the start position * @param end the end position * @param comparator {@link Comparator} * @return the array which is sorted * @param data type */ public static final ArrayWrapper qksort(final ArrayWrapper array , int start , int end , Comparator comparator) { if (start >= end) throw new IllegalArgumentException(start + " bigger than or equal " + end); //Stop the recursion when it is not possible to partition further. while (start < end - 1) { int index = 0; //Determine where to partition the elements. if ((index = ArraySort.partition(array , start , end , comparator)) < 0) throw new SortException(); //Recursively sort the left partition. ArraySort.qksort(array , start , ++index , comparator); //Iterate and sort the right partition. start = index; } return array; } /** * radix sort(基数排序)
* 基数排序并不局限于对整数进行排序,只要能吧元素分割成整数,就可以排序.Should use the double * size of data's space. * * @param array array * @param convert {@link Convert} the DATA covert to {@link Integer} * @param p 每个元素的位数. * @param k k<=data.length at the comment time. 具体该选择什么值作为基数取决于数据本身, * 同时考虑到空间的限制. * @param start start position(inclusive) * @param end end position(exclusive) * @param data type * @param array type * @return the array which has been sorted. * @throws IllegalArgumentException if start bigger than or equal end. */ @SuppressWarnings("unchecked") public static final ARRAY rxsort(ARRAY array , Convert convert , int p , int k , int start , int end) { final ArrayWrapper arrayWrapper = ArrayWrapper.wrap(array); return (ARRAY) ArraySort.rxsort(arrayWrapper , convert , p , k , start , end).array(); } /** * radix sort * @param array a unordered array * @param convert {@link Convert} the DATA covert to {@link Integer} * @param p the position * @param k k<=data.length at the comment time. * @param start the start position (inclusive) * @param end the end position (exclusive) * @return an ordered array * @param data type */ @SuppressWarnings("unchecked") public static final ArrayWrapper rxsort(ArrayWrapper array , Convert convert , int p , int k , int start , int end) { if (start >= end) throw new IllegalArgumentException(start + " can't bigger than or equal " + end); int[] counts = new int[k]; Object temp = Array.newInstance(array.array().getClass().getComponentType() , array.length()); ArrayWrapper tempWrapper = ArrayWrapper.wrap(temp); //Sort from the least significant position to the most significant. for (int n = 0 ; n < p ; n++) { //Initialize the counts. Arrays.fill(counts , 0); //Calculate the position value. int pval = (int) Math.pow(k , n); //Count the occurrences of each digit value. for (int j = start ; j < end ; j++) { int index = convert.convert((DATA) array.get(j)) / pval % k; counts[index] = counts[index] + 1; } //Adjust each count to reflect the counts before it. for (int i = 1 ; i < k ; i++) counts[i] = counts[i] + counts[i - 1]; //Use the counts to position each element where it belongs. for (int j = end - 1 ; j >= start ; j--) { int index = convert.convert((DATA) array.get(j)) / pval % k; tempWrapper.put(array.get(j) , counts[index] - 1 + start); counts[index] = counts[index] - 1; } System.arraycopy(temp , start , array.array() , start , end - start); } return array; } private ArraySort() { throw new AssertionError("No com.github.andyshao.arithmetic.ArraySort instances for you!"); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy