/**
* 实现排序算法:冒泡、插入、希尔、快速、归并、堆
*
* @author yhr
*
*/
public class SortUtil {
/**
* 冒泡排序(每趟确定一个值放后面,相邻比较) 稳定,最好n,最差n2,平均n2
*
* @param arr
*/
void bublleSort(int[] arr) {
int tmp;
for (int i = arr.length - 1; i > 0; i--) {
for (int j = 0; j < i; j++) {
if (arr[j] > arr[j + 1]) {
tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
/**
* 插入排序( 每趟取一个值往前比较,前面已排序) 稳定,最好n,最差n2,平均n2
*
* @param arr
*/
void insertSort(int[] arr) {
int current, j;
for (int i = 1; i < arr.length; i++) {
current = arr[i];
for (j = i - 1; j >= 0; j--) {
// 注意判断
if (current >= arr[j]) {
break;
}
arr[j + 1] = arr[j];
}
arr[j + 1] = current;
}
}
/**
* 希尔排序(带步长的插入排序) 不稳定
*
* @param arr
*/
void shellSort(int[] arr) {
int current, j;
for (int step = arr.length / 2; step >= 1; step /= 2) {
for (int i = step; i < arr.length; i++) {
current = arr[i];
for (j = i - step; j >= 0; j -= step) {
if (current >= arr[j]) {
break;
}
arr[j + step] = arr[j];
}
arr[j + step] = current;
}
}
}
/**
* 快速排序(每趟确定pivot的位置,然后递归) 不稳定,最好nlogn,最坏n2,平均nlogn
*
* @param arr
* @param start
* @param end
*/
void quickSort(int[] arr, int start, int end) {
if (start >= end) {
return;
}
// 选start或者end位置的值作为pivot
int pivot = arr[start];
int i = start + 1;
int j = end;
while (i <= j) {
while (i <= end && arr[i] < pivot) {
i++;
}
while (j >= start && arr[j] > pivot) {
j--;
}
// 可能arr[i]等于arr[j]等于pivot
if (i <= j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
// 有相等交换后指针需要移动
i++;
j--;
}
}
arr[start] = arr[j];
arr[j] = pivot;
quickSort(arr, start, j - 1);
quickSort(arr, j + 1, end);
}
/**
* 归并排序(分割、递归、合并) 稳定,最好nlogn,最坏nlogn,平均nlogn
*
* @param arr
* @param start
* @param end
* @param tmpArr
*/
void mergeSort(int[] arr, int start, int end, int[] tmpArr) {
if (start >= end) {
return;
}
int mid = (start + end) / 2;
mergeSort(arr, start, mid, tmpArr);
mergeSort(arr, mid + 1, end, tmpArr);
merge(arr, start, mid, end, tmpArr);
}
void merge(int[] arr, int lStart, int lEnd, int rEnd, int[] tmpArr) {
int rStart = lEnd + 1;
int tmpArrStart = lStart;
int arrStart = lStart;
while (lStart <= lEnd && rStart <= rEnd) {
if (arr[lStart] <= arr[rStart]) {
tmpArr[tmpArrStart++] = arr[lStart++];
} else {
tmpArr[tmpArrStart++] = arr[rStart++];
}
}
while (lStart <= lEnd) {
tmpArr[tmpArrStart++] = arr[lStart++];
}
while (rStart <= rEnd) {
tmpArr[tmpArrStart++] = arr[rStart++];
}
while (arrStart <= rEnd) {
arr[arrStart] = tmpArr[arrStart];
arrStart += 1;
}
}
/**
* 堆排序(通过下滤建堆和删除堆顶) 不稳定,最好nlogn,最坏nlogn,平均nlogn
*
* @param arr
*/
void heapSort(int[] arr) {
// 最后个节点为arr.length - 1,它的父节点即为最后个有孩子的节点为arr.length / 2 - 1
for (int i = arr.length / 2 - 1; i >= 0; i--) {
down(arr, arr.length, i);
}
for (int i = arr.length - 1; i > 0; i--) {
int tmp = arr[0];
arr[0] = arr[i];
arr[i] = tmp;
down(arr, i, 0);
}
}
void down(int[] arr, int n, int pos) {
// 取需要下滤的值向下比较一直到没有孩子或比较完成
int current = arr[pos];
for (int child = 2 * pos + 1; child < n; child = 2 * pos + 1) {
if (child != n - 1 && arr[child] < arr[child + 1]) {
child += 1;
}
if (arr[child] <= current) {
break;
}
arr[pos] = arr[child];
pos = child;
}
arr[pos] = current;
}
}
冒泡、插入、希尔、快速、归并、堆排序算法实现(Java)
最新推荐文章于 2020-11-16 00:15:44 发布