package org.bond.sort;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
/**
* 插入排序:直接插入排序;希尔排序
* 交换排序:冒泡排序;快速排序
* 选择排序:简单选择排序;堆排序
* 归并排序
* 基数排序
*/
public class SortingAlgorithm {
/**
* 归并排序
*
* @param data 待排序数组
*/
public static <T> void mergeSortAsc(T[] data) {
mergeSortAsc(data, 0, data.length - 1);
}
/**
* 归并排序
*
* @param data 待排序数组
* @param left 左下标
* @param right 有下标
*/
private static <T> void mergeSortAsc(T[] data, int left, int right) {
if (left >= right) {
return;
}
// 找出中间索引
int center = (left + right) / 2;
// 对左边数组进行递归
mergeSortAsc(data, left, center);
// 对右边数组进行递归
mergeSortAsc(data, center + 1, right);
// 合并
mergeSortAsc(data, left, center, right);
}
/**
* 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序
*
* @param data 数组对象
* @param left 左数组的第一个元素的索引
* @param center 左数组的最后一个元素的索引,center+1是右数组第一个元素的索引
* @param right 右数组最后一个元素的索引
*/
private static <T> void mergeSortAsc(T[] data, int left, int center, int right) {
// 克隆临时数组
T[] tmpArr = data.clone();
// 右数组第一个元素索引
int mid = center + 1;
// third 记录临时数组的索引
int third = left;
// 缓存左数组第一个元素的索引
int tmp = left;
while (left <= center && mid <= right) {
// 从两个数组中取出最小的放入临时数组
if (compare(data[left], data[mid]) < 1) {
tmpArr[third++] = data[left++];
} else {
tmpArr[third++] = data[mid++];
}
}
// 剩余部分依次放入临时数组
while (mid <= right) {
tmpArr[third++] = data[mid++];
}
while (left <= center) {
tmpArr[third++] = data[left++];
}
// 将临时数组中的内容拷贝回原数组中
// (原left-right范围的内容被复制回原数组)
while (tmp <= right) {
data[tmp] = tmpArr[tmp++];
}
}
/**
* 归并排序
*
* @param data 待排序数组
*/
public static <T> void mergeSortDesc(T[] data) {
mergeSortDesc(data, 0, data.length - 1);
}
/**
* 归并排序
*
* @param data 待排序数组
* @param left 左下标
* @param right 有下标
*/
private static <T> void mergeSortDesc(T[] data, int left, int right) {
if (left >= right) {
return;
}
// 找出中间索引
int center = (left + right) / 2;
// 对左边数组进行递归
mergeSortDesc(data, left, center);
// 对右边数组进行递归
mergeSortDesc(data, center + 1, right);
// 合并
mergeSortDesc(data, left, center, right);
}
/**
* 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序
*
* @param data 数组对象
* @param left 左数组的第一个元素的索引
* @param center 左数组的最后一个元素的索引,center+1是右数组第一个元素的索引
* @param right 右数组最后一个元素的索引
*/
private static <T> void mergeSortDesc(T[] data, int left, int center, int right) {
// 克隆临时数组
T[] tmpArr = data.clone();
// 右数组第一个元素索引
int mid = center + 1;
// third 记录临时数组的索引
int third = left;
// 缓存左数组第一个元素的索引
int tmp = left;
while (left <= center && mid <= right) {
// 从两个数组中取出最大的放入临时数组
if (compare(data[left], data[mid]) > -1) {
tmpArr[third++] = data[left++];
} else {
tmpArr[third++] = data[mid++];
}
}
// 剩余部分依次放入临时数组
while (mid <= right) {
tmpArr[third++] = data[mid++];
}
while (left <= center) {
tmpArr[third++] = data[left++];
}
// 将临时数组中的内容拷贝回原数组中
// (原left-right范围的内容被复制回原数组)
while (tmp <= right) {
data[tmp] = tmpArr[tmp++];
}
}
/**
* 归并排序
*
* @param data 待排序List
*/
public static <T> void mergeSortAsc(List<T> data) {
mergeSortAsc(data, 0, data.size() - 1);
}
/**
* 归并排序
*
* @param data 待排序List
* @param left 左下标
* @param right 有下标
*/
private static <T> void mergeSortAsc(List<T> data, int left, int right) {
if (left >= right) {
return;
}
// 找出中间索引
int center = (left + right) / 2;
// 对左边List进行递归
mergeSortAsc(data, left, center);
// 对右边List进行递归
mergeSortAsc(data, center + 1, right);
// 合并
mergeSortAsc(data, left, center, right);
}
/**
* 将两个List进行归并,归并前面2个List已有序,归并后依然有序
*
* @param data List对象
* @param left 左List的第一个元素的索引
* @param center 左List的最后一个元素的索引,center+1是右List第一个元素的索引
* @param right 右List最后一个元素的索引
*/
private static <T> void mergeSortAsc(List<T> data, int left, int center, int right) {
// 克隆临时List
List<T> tmpArr = new ArrayList<T>(data.size());
for (int i = 0; i < data.size(); i++) {
tmpArr.add(i, data.get(i));
}
// 右List第一个元素索引
int mid = center + 1;
// third 记录临时List的索引
int third = left;
// 缓存左List第一个元素的索引
int tmp = left;
while (left <= center && mid <= right) {
// 从两个List中取出最小的放入临时List
if (compare(data.get(left), data.get(mid)) < 1) {
tmpArr.set(third++, data.get(left++));
} else {
tmpArr.set(third++, data.get(mid++));
}
}
// 剩余部分依次放入临时List
while (mid <= right) {
tmpArr.set(third++, data.get(mid++));
}
while (left <= center) {
tmpArr.set(third++, data.get(left++));
}
// 将临时List中的内容拷贝回原List中
// (原left-right范围的内容被复制回原List)
while (tmp <= right) {
data.set(tmp, tmpArr.get(tmp++));
}
}
/**
* 归并排序
*
* @param data 待排序List
*/
public static <T> void mergeSortDesc(List<T> data) {
mergeSortDesc(data, 0, data.size() - 1);
}
/**
* 归并排序
*
* @param data 待排序List
* @param left 左下标
* @param right 有下标
*/
private static <T> void mergeSortDesc(List<T> data, int left, int right) {
if (left >= right) {
return;
}
// 找出中间索引
int center = (left + right) / 2;
// 对左边List进行递归
mergeSortDesc(data, left, center);
// 对右边List进行递归
mergeSortDesc(data, center + 1, right);
// 合并
mergeSortDesc(data, left, center, right);
}
/**
* 将两个List进行归并,归并前面2个List已有序,归并后依然有序
*
* @param data List对象
* @param left 左List的第一个元素的索引
* @param center 左List的最后一个元素的索引,center+1是右List第一个元素的索引
* @param right 右List最后一个元素的索引
*/
private static <T> void mergeSortDesc(List<T> data, int left, int center, int right) {
// 克隆临时List
List<T> tmpArr = new ArrayList<T>(data.size());
for (int i = 0; i < data.size(); i++) {
tmpArr.add(i, data.get(i));
}
// 右List第一个元素索引
int mid = center + 1;
// third 记录临时List的索引
int third = left;
// 缓存左List第一个元素的索引
int tmp = left;
while (left <= center && mid <= right) {
// 从两个List中取出最大的放入临时List
if (compare(data.get(left), data.get(mid)) > -1) {
tmpArr.set(third++, data.get(left++));
} else {
tmpArr.set(third++, data.get(mid++));
}
}
// 剩余部分依次放入临时List
while (mid <= right) {
tmpArr.set(third++, data.get(mid++));
}
while (left <= center) {
tmpArr.set(third++, data.get(left++));
}
// 将临时List中的内容拷贝回原List中
// (原left-right范围的内容被复制回原List)
while (tmp <= right) {
data.set(tmp, tmpArr.get(tmp++));
}
}
/**
* 插入排序ASC
*
* @param data 待排序数据数组
*/
public static <T> void insertSortAsc(T[] data) {
for (int i = 1; i < data.length; i++) {
int j = i - 1;
T value = data[i];
while (j >= 0 && compare(data[j], value) > 0) {
data[j + 1] = data[j];
j--;
}
data[j + 1] = value;
}
}
/**
* 插入排序Desc
*
* @param data 待排序数组
*/
public static <T> void insertSortDesc(T[] data) {
for (int i = 1; i < data.length; i++) {
int j = i - 1;
T value = data[i];
while (j >= 0 && compare(data[j], value) < 0) {
data[j + 1] = data[j];
j--;
}
data[j + 1] = value;
}
}
/**
* 插入排序Asc
*
* @param data 待排序List
*/
public static <T> void insertSortAsc(List<T> data) {
for (int i = 1; i < data.size(); i++) {
int j = i - 1;
T value = data.get(i);
while (j >= 0 && compare(data.get(j), value) > 0) {
data.set(j + 1, data.get(j));
j--;
}
data.set(j + 1, value);
}
}
/**
* 插入排序Desc
*
* @param data 待排序List
*/
public static <T> void insertSortDesc(List<T> data) {
for (int i = 1; i < data.size(); i++) {
int j = i - 1;
T value = data.get(i);
while (j >= 0 && compare(data.get(j), value) < 0) {
data.set(j + 1, data.get(j));
j--;
}
data.set(j + 1, value);
}
}
/**
* 希尔排序Asc
*
* @param data 待排序数组
*/
public static <T> void shellSortAsc(T[] data) {
double len = data.length;
while (true) {
len = Math.ceil(len / 2);
//获取增量d(n/2,n为要排序数的个数)
int d = (int) len;
for (int x = 0; x < d; x++) {
for (int i = x + d; i < data.length; i += d) {
int j = i - d;
T temp = data[i];
for (; j >= 0 && compare(temp, data[j]) == -1; j -= d) {
data[j + d] = data[j];
}
data[j + d] = temp;
}
}
if (d == 1) {
break;
}
}
}
/**
* 希尔排序Desc
*
* @param data 待排序数组
*/
public static <T> void shellSortDesc(T[] data) {
double len = data.length;
while (true) {
len = Math.ceil(len / 2);
//获取增量d(n/2,n为要排序数的个数)
int d = (int) len;
for (int x = 0; x < d; x++) {
for (int i = x + d; i < data.length; i += d) {
int j = i - d;
T temp = data[i];
for (; j >= 0 && compare(temp, data[j]) == 1; j -= d) {
data[j + d] = data[j];
}
data[j + d] = temp;
}
}
if (d == 1) {
break;
}
}
}
/**
* 希尔排序Asc
*
* @param data 待排序List
*/
public static <T> void shellSortAsc(List<T> data) {
double len = data.size();
while (true) {
len = Math.ceil(len / 2);
//获取增量d(n/2,n为要排序数的个数)
int d = (int) len;
for (int x = 0; x < d; x++) {
for (int i = x + d; i < data.size(); i += d) {
int j = i - d;
T temp = data.get(i);
for (; j >= 0 && compare(temp, data.get(j)) == -1; j -= d) {
data.set(j + d, data.get(j));
}
data.set(j + d, temp);
}
}
if (d == 1) {
break;
}
}
}
/**
* 希尔排序Desc
*
* @param data 待排序List
*/
public static <T> void shellSortDesc(List<T> data) {
double len = data.size();
while (true) {
len = Math.ceil(len / 2);
//获取增量d(n/2,n为要排序数的个数)
int d = (int) len;
for (int x = 0; x < d; x++) {
for (int i = x + d; i < data.size(); i += d) {
int j = i - d;
T temp = data.get(i);
for (; j >= 0 && compare(temp, data.get(j)) == 1; j -= d) {
data.set(j + d, data.get(j));
}
data.set(j + d, temp);
}
}
if (d == 1) {
break;
}
}
}
/**
* 冒泡排序Asc
*
* @param data 待排序数组
*/
public static <T> void bubbleSortAsc(T[] data) {
for (int i = 0; i < data.length - 1; i++) {
for (int j = i + 1; j < data.length; j++) {
if (compare(data[i], data[j]) > 0) {
T temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
}
}
/**
* 冒泡排序Desc
*
* @param data 待排序数组
*/
public static <T> void bubbleSortDesc(T[] data) {
for (int i = 0; i < data.length - 1; i++) {
for (int j = i + 1; j < data.length; j++) {
if (compare(data[i], data[j]) < 0) {
T temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
}
}
/**
* 冒泡排序Asc
*
* @param data 待排序List
*/
public static <T> void bubbleSortAsc(List<T> data) {
for (int i = 0; i < data.size() - 1; i++) {
for (int j = i + 1; j < data.size(); j++) {
if (compare(data.get(i), data.get(j)) > 0) {
T temp = data.get(i);
data.set(i, data.get(j));
data.set(j, temp);
}
}
}
}
/**
* 冒泡排序Desc
*
* @param data 待排序List
*/
public static <T> void bubbleSortDesc(List<T> data) {
for (int i = 0; i < data.size() - 1; i++) {
for (int j = i + 1; j < data.size(); j++) {
if (compare(data.get(i), data.get(j)) < 0) {
T temp = data.get(i);
data.set(i, data.get(j));
data.set(j, temp);
}
}
}
}
/**
* 快速排序ASC
*
* @param data 待排序数据数组
*/
public static <T> void quickSortAsc(T[] data) {
int left = 0;
int right = data.length - 1;
quickSortAsc(data, left, right);
}
/**
* 快速排序Desc
*
* @param data 待排序数据数组
*/
public static <T> void quickSortDesc(T[] data) {
int left = 0;
int right = data.length - 1;
quickSortDesc(data, left, right);
}
/**
* 快速排序ASC
*
* @param data 待排序数据List
*/
public static <T> void quickSortAsc(List<T> data) {
int left = 0;
int right = data.size() - 1;
quickSortAsc(data, left, right);
}
/**
* 快速排序Desc
*
* @param data 待排序数据List
*/
public static <T> void quickSortDesc(List<T> data) {
int left = 0;
int right = data.size() - 1;
quickSortDesc(data, left, right);
}
/**
* 快速排序ASC
*
* @param data 待排序数据数组
* @param left 左边下标
* @param right 右边下标
*/
private static <T> void quickSortAsc(T[] data, int left, int right) {
if (left < right) {
T base = data[left];//选择第一个值为基准值
int i = left, j = right;
do {
//将数组分成两部分,左边小于基准值;右边大于基准值
while (compare(data[i], base) == -1 && i < right) {
i++;
}
while (compare(data[j], base) == 1 && j > left) {
j--;
}
if (i <= j) {
T temp = data[i];
data[i] = data[j];
data[j] = temp;
i++;
j--;
}
} while (i <= j);
if (left < j) {
quickSortAsc(data, left, j);
}
if (right > i) {
quickSortAsc(data, i, right);
}
}
}
/**
* 快速排序Desc
*
* @param data 待排序数据数组
* @param left 左边下标
* @param right 右边下标
*/
private static <T> void quickSortDesc(T[] data, int left, int right) {
if (left < right) {
T base = data[left];//选择第一个值为基准值
int i = left, j = right;
do {
//将数组分成两部分,左边小于基准值;右边大于基准值
while (compare(data[i], base) == 1 && i < right) {
i++;
}
while (compare(data[j], base) == -1 && j > left) {
j--;
}
if (i <= j) {
T temp = data[i];
data[i] = data[j];
data[j] = temp;
i++;
j--;
}
} while (i <= j);
if (left < j) {
quickSortDesc(data, left, j);
}
if (right > i) {
quickSortDesc(data, i, right);
}
}
}
/**
* 快速排序ASC
*
* @param data 待排序数据List
* @param left 左边下标
* @param right 右边下标
*/
private static <T> void quickSortAsc(List<T> data, int left, int right) {
if (left < right) {
T base = data.get(left);//选择第一个值为基准值
int i = left, j = right;
do {
//将数组分成两部分,左边小于基准值;右边大于基准值
while (compare(data.get(i), base) == -1 && i < right) {
i++;
}
while (compare(data.get(j), base) == 1 && j > left) {
j--;
}
if (i <= j) {
T temp = data.get(i);
data.set(i, data.get(j));
data.set(j, temp);
i++;
j--;
}
} while (i <= j);
if (left < j) {
quickSortAsc(data, left, j);
}
if (right > i) {
quickSortAsc(data, i, right);
}
}
}
/**
* 快速排序Desc
*
* @param data 待排序数据List
* @param left 左边下标
* @param right 右边下标
*/
private static <T> void quickSortDesc(List<T> data, int left, int right) {
if (left < right) {
T base = data.get(left);//选择第一个值为基准值
int i = left, j = right;
do {
//将数组分成两部分,左边小于基准值;右边大于基准值
while (compare(data.get(i), base) == 1 && i < right) {
i++;
}
while (compare(data.get(j), base) == -1 && j > left) {
j--;
}
if (i <= j) {
T temp = data.get(i);
data.set(i, data.get(j));
data.set(j, temp);
i++;
j--;
}
} while (i <= j);
if (left < j) {
quickSortDesc(data, left, j);
}
if (right > i) {
quickSortDesc(data, i, right);
}
}
}
/**
* 选择排序Asc
*
* @param data 待排序数组
*/
public static <T> void selectSortAsc(T[] data) {
for (int i = 0; i < data.length; i++) {
int minIndex = getMinIndex(data, i, data.length - 1);
if (minIndex != i) {
T temp = data[i];
data[i] = data[minIndex];
data[minIndex] = temp;
}
}
}
/**
* 选择排序Asc
*
* @param data 待排序List
*/
public static <T> void selectSortAsc(List<T> data) {
for (int i = 0; i < data.size(); i++) {
int minIndex = getMinIndex(data, i, data.size() - 1);
if (minIndex != i) {
T temp = data.get(i);
data.set(i, data.get(minIndex));
data.set(minIndex, temp);
}
}
}
/**
* 选择排序Desc
*
* @param data 待排序数组
*/
public static <T> void selectSortDesc(T[] data) {
for (int i = 0; i < data.length; i++) {
int minIndex = getMaxIndex(data, i, data.length - 1);
if (minIndex != i) {
T temp = data[i];
data[i] = data[minIndex];
data[minIndex] = temp;
}
}
}
/**
* 选择排序Desc
*
* @param data 待排序List
*/
public static <T> void selectSortDesc(List<T> data) {
for (int i = 0; i < data.size(); i++) {
int minIndex = getMaxIndex(data, i, data.size() - 1);
if (minIndex != i) {
T temp = data.get(i);
data.set(i, data.get(minIndex));
data.set(minIndex, temp);
}
}
}
/**
* 堆排序ASC
*
* @param data 待排序数组
*/
public static <T> void heapSortAsc(T[] data) {
heapSortAsc(data, data.length - 1);
}
/**
* 堆排序ASC
*
* @param data
* @param index
*/
private static <T> void heapSortAsc(T[] data, int index) {
if (index > 0) {
initHeapAsc(data, index);
T temp = data[0];
data[0] = data[index];
data[index] = temp;
heapSortAsc(data, index - 1);
}
}
/**
* 初始化堆,找出最大的放在堆顶
*
* @param data
* @param index
*/
private static <T> void initHeapAsc(T[] data, int index) {
int m = (index + 1) / 2;
for (int i = 0; i < m; i++) {
boolean flag = buildHeapAsc(data, index, i);
//如果子节点之间有交换,就要重新开始
if (flag) {
i = -1;
}
}
}
/**
* 返回一个标记,如果有根与孩子交换就要重新从顶根开始查找不满足最大堆树结构
*
* @param data
* @param index
* @param i
* @return
*/
private static <T> boolean buildHeapAsc(T[] data, int index, int i) {
int lNode = 2 * i + 1;
int rNode = 2 * i + 2;
if (rNode > index) {//判断是否有右孩子,没有的话直接比较,小于交换
if (compare(data[i], data[lNode]) == -1) {
T temp = data[i];
data[i] = data[lNode];
data[lNode] = temp;
return true;
} else {
return false;
}
}
//在根与两个孩子之间找出最大的那个值进行交换
if (compare(data[i], data[lNode]) == -1) {
if (compare(data[lNode], data[rNode]) == 1) {
//交换根与左孩子的值
T temp = data[i];
data[i] = data[lNode];
data[lNode] = temp;
return true;
} else {
//交换根与右孩子的值
T temp = data[i];
data[i] = data[rNode];
data[rNode] = temp;
return true;
}
} else if (compare(data[i], data[rNode]) == -1) {
//交换根与右孩子的值
T temp = data[i];
data[i] = data[rNode];
data[rNode] = temp;
return true;
}
return false;
}
/**
* 堆排序Desc
*
* @param data 待排序数组
*/
public static <T> void heapSortDesc(T[] data) {
heapSortDesc(data, data.length - 1);
}
/**
* 堆排序Desc
*
* @param data
* @param index
*/
private static <T> void heapSortDesc(T[] data, int index) {
if (index > 0) {
initHeapDesc(data, index);
T temp = data[0];
data[0] = data[index];
data[index] = temp;
heapSortDesc(data, index - 1);
}
}
/**
* 初始化堆,找出最大的放在堆顶
*
* @param data
* @param index
*/
private static <T> void initHeapDesc(T[] data, int index) {
int m = (index + 1) / 2;
for (int i = 0; i < m; i++) {
boolean flag = buildHeapDesc(data, index, i);
//如果子节点之间有交换,就要重新开始
if (flag) {
i = -1;
}
}
}
/**
* 返回一个标记,如果有根与孩子交换就要重新从顶根开始查找不满足最大堆树结构
*
* @param data
* @param index
* @param i
* @return
*/
private static <T> boolean buildHeapDesc(T[] data, int index, int i) {
int lNode = 2 * i + 1;
int rNode = 2 * i + 2;
if (rNode > index) {//判断是否有右孩子,没有的话直接比较,小于交换
if (compare(data[i], data[lNode]) == 1) {
T temp = data[i];
data[i] = data[lNode];
data[lNode] = temp;
return true;
} else {
return false;
}
}
//在根与两个孩子之间找出最大的那个值进行交换
if (compare(data[i], data[lNode]) == 1) {
if (compare(data[lNode], data[rNode]) == -1) {
//交换根与左孩子的值
T temp = data[i];
data[i] = data[lNode];
data[lNode] = temp;
return true;
} else {
//交换根与右孩子的值
T temp = data[i];
data[i] = data[rNode];
data[rNode] = temp;
return true;
}
} else if (compare(data[i], data[rNode]) == 1) {
//交换根与右孩子的值
T temp = data[i];
data[i] = data[rNode];
data[rNode] = temp;
return true;
}
return false;
}
/**
* 堆排序ASC
*
* @param data 待排序List
*/
public static <T> void heapSortAsc(List<T> data) {
heapSortAsc(data, data.size() - 1);
}
/**
* 堆排序ASC
*
* @param data
* @param index
*/
private static <T> void heapSortAsc(List<T> data, int index) {
if (index > 0) {
initHeapAsc(data, index);
T temp = data.get(0);
data.set(0, data.get(index));
data.set(index, temp);
heapSortAsc(data, index - 1);
}
}
/**
* 初始化堆,找出最大的放在堆顶
*
* @param data
* @param index
*/
private static <T> void initHeapAsc(List<T> data, int index) {
int m = (index + 1) / 2;
for (int i = 0; i < m; i++) {
boolean flag = buildHeapAsc(data, index, i);
//如果子节点之间有交换,就要重新开始
if (flag) {
i = -1;
}
}
}
/**
* 返回一个标记,如果有根与孩子交换就要重新从顶根开始查找不满足最大堆树结构
*
* @param data
* @param index
* @param i
* @return
*/
private static <T> boolean buildHeapAsc(List<T> data, int index, int i) {
int lNode = 2 * i + 1;
int rNode = 2 * i + 2;
if (rNode > index) {//判断是否有右孩子,没有的话直接比较,小于交换
if (compare(data.get(i), data.get(lNode)) == -1) {
T temp = data.get(i);
data.set(i, data.get(lNode));
data.set(lNode, temp);
return true;
} else {
return false;
}
}
//在根与两个孩子之间找出最大的那个值进行交换
if (compare(data.get(i), data.get(lNode)) == -1) {
if (compare(data.get(lNode), data.get(rNode)) == 1) {
//交换根与左孩子的值
T temp = data.get(i);
data.set(i, data.get(lNode));
data.set(lNode, temp);
return true;
} else {
//交换根与右孩子的值
T temp = data.get(i);
data.set(i, data.get(rNode));
data.set(rNode, temp);
return true;
}
} else if (compare(data.get(i), data.get(rNode)) == -1) {
//交换根与右孩子的值
T temp = data.get(i);
data.set(i, data.get(rNode));
data.set(rNode, temp);
return true;
}
return false;
}
/**
* 堆排序Desc
*
* @param data 待排序List
*/
public static <T> void heapSortDesc(List<T> data) {
heapSortDesc(data, data.size() - 1);
}
/**
* 堆排序Desc
*
* @param data
* @param index
*/
private static <T> void heapSortDesc(List<T> data, int index) {
if (index > 0) {
initHeapDesc(data, index);
T temp = data.get(0);
data.set(0, data.get(index));
data.set(index, temp);
heapSortDesc(data, index - 1);
}
}
/**
* 初始化堆,找出最大的放在堆顶
*
* @param data
* @param index
*/
private static <T> void initHeapDesc(List<T> data, int index) {
int m = (index + 1) / 2;
for (int i = 0; i < m; i++) {
boolean flag = buildHeapDesc(data, index, i);
//如果子节点之间有交换,就要重新开始
if (flag) {
i = -1;
}
}
}
/**
* 返回一个标记,如果有根与孩子交换就要重新从顶根开始查找不满足最大堆树结构
*
* @param data
* @param index
* @param i
* @return
*/
private static <T> boolean buildHeapDesc(List<T> data, int index, int i) {
int lNode = 2 * i + 1;
int rNode = 2 * i + 2;
if (rNode > index) {//判断是否有右孩子,没有的话直接比较,小于交换
if (compare(data.get(i), data.get(lNode)) == 1) {
T temp = data.get(i);
data.set(i, data.get(lNode));
data.set(lNode, temp);
return true;
} else {
return false;
}
}
//在根与两个孩子之间找出最大的那个值进行交换
if (compare(data.get(i), data.get(lNode)) == 1) {
if (compare(data.get(lNode), data.get(rNode)) == -1) {
//交换根与左孩子的值
T temp = data.get(i);
data.set(i, data.get(lNode));
data.set(lNode, temp);
return true;
} else {
//交换根与右孩子的值
T temp = data.get(i);
data.set(i, data.get(rNode));
data.set(rNode, temp);
return true;
}
} else if (compare(data.get(i), data.get(rNode)) == 1) {
//交换根与右孩子的值
T temp = data.get(i);
data.set(i, data.get(rNode));
data.set(rNode, temp);
return true;
}
return false;
}
/**
* 比较大小
*
* @param val1
* @param val2
* @return 1:val1>val2;0:val1=val2;-1:val1<val2
*/
private static <T> int compare(T val1, T val2) {
int rtn = 0;
if (val1.getClass().getName().equals("java.lang.Integer")) {
Integer v1 = (Integer) val1;
Integer v2 = (Integer) val2;
rtn = Integer.compare(v1, v2);
} else if (val1.getClass().getName().equals("java.lang.Float")) {
Float v1 = (Float) val1;
Float v2 = (Float) val2;
rtn = Float.compare(v1, v2);
} else if (val1.getClass().getName().equals("java.lang.Double")) {
Double v1 = (Double) val1;
Double v2 = (Double) val2;
rtn = Double.compare(v1, v2);
} else if (val1.getClass().getName().equals("java.lang.Character")) {
Character v1 = (Character) val1;
Character v2 = (Character) val2;
return Character.compare(v1, v2);
} else if (val1.getClass().getName().equals("java.lang.String")) {
String v1 = (String) val1;
String v2 = (String) val2;
return v1.compareTo(v2);
}
return rtn;
}
/**
* 获取数组中最大值的位置
*
* @param data
* @param left
* @param right
* @return
*/
private static <T> int getMaxIndex(T[] data, int left, int right) {
int index = left;
T maxValue = data[left];
for (int i = left + 1; i <= right; i++) {
if (compare(data[i], maxValue) == 1) {
maxValue = data[i];
index = i;
}
}
return index;
}
/**
* 获取List中最大值的位置
*
* @param data
* @param left
* @param right
* @return
*/
private static <T> int getMaxIndex(List<T> data, int left, int right) {
int index = left;
T maxValue = data.get(left);
for (int i = left + 1; i <= right; i++) {
if (compare(data.get(i), maxValue) == 1) {
maxValue = data.get(i);
index = i;
}
}
return index;
}
/**
* 获取数组中最小值的位置
*
* @param data
* @param left
* @param right
* @return
*/
private static <T> int getMinIndex(T[] data, int left, int right) {
int index = left;
T minValue = data[left];
for (int i = left + 1; i <= right; i++) {
if (compare(data[i], minValue) == -1) {
minValue = data[i];
index = i;
}
}
return index;
}
/**
* 获取List中最小值的位置
*
* @param data
* @param left
* @param right
* @return
*/
private static <T> int getMinIndex(List<T> data, int left, int right) {
int index = left;
T minValue = data.get(left);
for (int i = left + 1; i <= right; i++) {
if (compare(data.get(i), minValue) == -1) {
minValue = data.get(i);
index = i;
}
}
return index;
}
}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
package org.bond.test;
import java.util.Random;
import java.util.List;
import java.util.ArrayList;
import org.bond.sort.SortingAlgorithm;
public class Start {
public static void main(String[] args) throws Exception {
try {
long beginTime = System.currentTimeMillis();
//test1();
test2();
long endTime = System.currentTimeMillis();
System.out.println("\r\n时间:" + (endTime - beginTime));
} catch (Exception e) {
e.printStackTrace();
}
}
private static void test1() {
Random rd = new Random();
Integer[] data = new Integer[10];
for (int i = 0; i < data.length; i++) {
data[i] = rd.nextInt(100);
}
System.out.println("\r\n排序之前:");
for (int i = 0; i < data.length; i++) {
System.out.print(data[i]);
System.out.print(",");
}
SortingAlgorithm.mergeSortDesc(data);
System.out.println("\r\n排序之后:");
for (int i = 0; i < data.length; i++) {
System.out.print(data[i]);
System.out.print(",");
}
}
private static void test2() {
Random rd = new Random();
List<Integer> data = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
data.add(rd.nextInt(100));
}
System.out.println("\r\n排序之前:");
for (int i = 0; i < data.size(); i++) {
System.out.print(data.get(i));
System.out.print(",");
}
SortingAlgorithm.mergeSortDesc(data);
System.out.println("\r\n排序之后:");
for (int i = 0; i < data.size(); i++) {
System.out.print(data.get(i));
System.out.print(",");
}
}
}