System.out.println("============================================");
int[] dest = ShellSort.sort(PrintArray.SRC);
PrintArray.print(dest);
}
}
**5、归并排序**
public class MergeSort {
public static int[] sort(int[] array) {
if (array.length < 2) return array;
/*切分数组,然后递归调用*/
int mid = array.length / 2;
int[] left = Arrays.copyOfRange(array, 0, mid);
int[] right = Arrays.copyOfRange(array, mid, array.length);
return merge(sort(left), sort(right));
}
/**
* 归并排序——将两段排序好的数组结合成一个排序数组
*
* @param left
* @param right
* @return
*/
public static int[] merge(int[] left, int[] right) {
int[] result = new int[left.length + right.length];
for (int index = 0, i = 0, j = 0; index < result.length; index++) {
if (i >= left.length)/*左边数组已经取完,完全取右边数组的值即可*/
result[index] = right[j++];
else if (j >= right.length)/*右边数组已经取完,完全取左边数组的值即可*/
result[index] = left[i++];
else if (left[i] > right[j])/*左边数组的元素值大于右边数组,取右边数组的值*/
result[index] = right[j++];
else/*右边数组的元素值大于左边数组,取左边数组的值*/
result[index] = left[i++];
}
System.out.print("左子数组:");
PrintArray.print(left);
System.out.print("右子数组:");
PrintArray.print(right);
System.out.print("合并后数组:");
PrintArray.print(result);
System.out.println("--------------------");
return result;
}
public static void main(String[] args) {
PrintArray.print(PrintArray.SRC);
System.out.println("============================================");
int[] dest = MergeSort.sort(PrintArray.SRC);
PrintArray.print(dest);
}
}
**6、快速排序**
public class QuickSort {
public static int[] sort(int[] array, int start, int end) {
if (array.length < 1 || start < 0 || end >= array.length || start > end)
return null;
/*数据分割成独立的两部分时,从哪儿分区的指示器*/
int zoneIndex = partition(array, start, end);
if (zoneIndex > start)
sort(array, start, zoneIndex - 1);
if (zoneIndex < end)
sort(array, zoneIndex + 1, end);
System.out.println("本轮排序后的数组");
PrintArray.printIndex(array,start,end);
System.out.println("--------------------");
return array;
}
/**
* 快速排序算法——partition
* @param array
* @param start
* @param end
* @return
*/
public static int partition(int[] array, int start, int end) {
int pivot = (int) (start + Math.random() * (end - start + 1));
System.out.println("开始下标:"+start+",结束下标:"+end+",基准数下标:"
+pivot+",元素值:"+array[pivot]);
/*zoneIndex是分割指示器
从业务上来说:比基准数小的,放到指示器的左边,比基准数大的,放到指示器的右边,
* 但在实际实现时,通过移动比基准数小的元素和分割指示器本身也可以达到一样的效果*/
int zoneIndex = start - 1;
swap(array, pivot, end);/*将基准数和数组尾元素交换位置*/
for (int i = start; i <= end; i++){
if (array[i] <= array[end]) {/*当前元素小于等于基准数*/
zoneIndex++;/*首先分割指示器累加*/
if (i > zoneIndex)/*当前元素在分割指示器的右边时,交换当前元素和分割指示器元素*/
swap(array, i, zoneIndex);
}
System.out.println("zoneIndex:"+zoneIndex+",i:"+i);
PrintArray.printIndex(array,start,end);
}
System.out.println("---------------");
return zoneIndex;
}
/**
* 交换数组内两个元素
* @param array
* @param i
* @param j
*/
public static void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public static void main(String[] args) {
PrintArray.print(PrintArray.SRC);
System.out.println("============================================");
int[] dest = QuickSort.sort(PrintArray.SRC,0,PrintArray.SRC.length-1);
PrintArray.print(dest);
}
}
**7、堆排序**
public class HeapSort {
//声明全局变量,用于记录数组array的长度;
private static int len;
public static int[] sort(int[] array) {
len = array.length;
if (len < 1) return array;
//1.构建一个最大堆
buildMaxHeap(array);
//2.循环将堆首位(最大值)与末位交换,然后在重新调整最大堆
while (len > 0) {
swap(array, 0, len - 1);
len--;
adjustHeap(array, 0);
PrintArray.print(array);
System.out.println("--------------------");
}
return array;
}
/**
* 建立最大堆
*
* @param array
*/
public static void buildMaxHeap(int[] array) {
//从最后一个非叶子节点开始向上构造最大堆
for (int i = (len/2-1); i >= 0; i--) {
adjustHeap(array, i);
}
System.out.println("构造完成最大堆");
PrintArray.print(array);
System.out.println("============================================");
}
/**
* 调整使之成为最大堆
*
* @param array
* @param i
*/
public static void adjustHeap(int[] array, int i) {
int maxIndex = i;
int left = 2*i+1;
int right = 2*(i+1);
//如果有左子树,且左子树大于父节点,则将最大指针指向左子树
if (left < len && array[left] > array[maxIndex])
maxIndex = left;
//如果有右子树,且右子树大于父节点,则将最大指针指向右子树
if (right < len && array[right] > array[maxIndex])
maxIndex = right;
//如果父节点不是最大值,则将父节点与最大值交换,并且递归调整与父节点交换的位置。
if (maxIndex != i) {
swap(array, maxIndex, i);
adjustHeap(array, maxIndex);
}
}
/**
* 交换数组内两个元素
* @param array
* @param i
* @param j
*/
public static void swap(int[] array, int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
public static void main(String[] args) {
PrintArray.print(PrintArray.SRC);
System.out.println("============================================");
int[] dest = HeapSort.sort(PrintArray.SRC);
PrintArray.print(dest);
}
}
**8、计数排序**
public class CountingSort {
public static int[] sort(int[] array) {
if (array.length == 0) return array;
/*寻找数组中最大值,最小值
* bias:偏移量,用以定位原始数组每个元素在计数数组中的下标位置*/
int bias, min = array[0], max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] > max)
max = array[i];
if (array[i] < min)
min = array[i];
}
bias = 0 - min;
/*获得计数数组的容量*/
int[] counterArray = new int[max - min + 1];
Arrays.fill(counterArray, 0);
/*遍历整个原始数组,将原始数组中每个元素值转化为计数数组下标,
并将计数数组下标对应的元素值大小进行累加*/
for (int i = 0; i < array.length; i++) {
counterArray[array[i] + bias]++;
}
System.out.println("计数数组为:");
PrintArray.print(counterArray);
System.out.println("============================================");
int index = 0;/*访问原始数组时的下标计数器*/
int i = 0;/*访问计数数组时的下标计数器*/
/*访问计数数组,将计数数组中的元素转换后,重新写回原始数组*/
while (index < array.length) {
/*只要计数数组中当前下标元素的值不为0,就将计数数组中的元素转换后,重新写回原始数组*/
if (counterArray[i] != 0) {
array[index] = i - bias;
counterArray[i]--;
index++;
} else
i++;
PrintArray.print(counterArray);
PrintArray.print(array);
System.out.println("--------------------");
}
return array;
}
final static int[] src = {5,4,5,0,3,6,2,0,2,4,3,3};
public static void main(String[] args) {
PrintArray.print(src);
System.out.println("============================================");
int[] dest = CountingSort.sort(src);
PrintArray.print(dest);
}
}
**9、桶排序**
public class BucketSort {
/**
*
* @param array
* @param bucketSize BucketSize,作为每个桶所能放置多少个不同数值
* (例如当BucketSize==5时,该桶可以存放{1,2,3,4,5}这几种数字,
* 但是容量不限,即可以存放100个3);
* @return
*/
public static ArrayList<Integer> sort(ArrayList<Integer> array, int bucketSize) {
if (array == null || array.size() < 2)
return array;
int max = array.get(0), min = array.get(0);
// 找到最大值最小值
for (int i = 0; i < array.size(); i++) {
if (array.get(i) > max)
max = array.get(i);
if (array.get(i) < min)
min = array.get(i);
}
/*获得桶的数量*/
int bucketCount = (max - min) / bucketSize + 1;
/*构建桶*/
ArrayList<ArrayList<Integer>> bucketArr = new ArrayList<>(bucketCount);
ArrayList<Integer> resultArr = new ArrayList<>();
for (int i = 0; i < bucketCount; i++) {
bucketArr.add(new ArrayList<Integer>());
}
/*将原始数组中的数据分配到桶中*/
for (int i = 0; i < array.size(); i++) {
bucketArr.get((array.get(i) - min) / bucketSize).add(array.get(i));
}
/*看看桶中数据的分布*/
for (int i = 0; i < bucketArr.size(); i++) {
System.out.print("第"+i+"个桶包含数据:");
PrintArray.printObject(bucketArr.get(i));
}
for (int i = 0; i < bucketCount; i++) {
if (bucketSize == 1) {
for (int j = 0; j < bucketArr.get(i).size(); j++)
resultArr.add(bucketArr.get(i).get(j));
} else {
if (bucketCount == 1)
bucketSize--;
/*对桶中的数据再次用桶进行排序*/
ArrayList<Integer> temp = sort(bucketArr.get(i), bucketSize);
for (int j = 0; j < temp.size(); j++)
resultArr.add(temp.get(j));
}
}
return resultArr;
}
public static void main(String[] args) {
ArrayList<Integer> array = new ArrayList<>();
array.add(86);
array.add(11);
array.add(77);
array.add(23);
array.add(32);
array.add(45);
array.add(58);
array.add(63);
array.add(93);
array.add(4);
array.add(37);
array.add(22);
PrintArray.printObject(array);
System.out.println("============================================");
ArrayList<Integer> dest = BucketSort.sort(array,2);
PrintArray.printObject(dest);
}
}
**10、基数排序**
public class RadixSort {
public static int[] sort(int[] array) {
if (array == null || array.length < 2)
return array;