常用排序算法(Java描述)
代码如下:
package cn.ganlixin.sort;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.junit.Test;
import java.util.Objects;
public class SortTest {
@Test
public void testBubbleSort() {
Person[] arr = new Person[4];
arr[0] = new Person(5, "abc");
arr[1] = new Person(3, "xyz");
arr[2] = new Person(7, "qaq");
arr[3] = new Person(1, "lol");
// bubbleSort(arr);
// selectSort(arr);
// insertSort(arr);
// int[] gapList = {7, 5, 3, 1};
// shellSort(arr, gapList);
// quickSort(arr, 0, arr.length - 1);
mergeSort(arr, 0, arr.length - 1, new Comparable[4]);
printArray(arr);
}
@Data
@AllArgsConstructor
private static class Person implements Comparable<Person> {
// 注意,对象之间如果需要进行比较,则必须实现Comparable接口,并重写compareTo方法
private Integer id;
private String name;
@Override
public int compareTo(Person otherPerson) {
if (Objects.isNull(this.id) || Objects.isNull(otherPerson) || Objects.isNull(otherPerson.getId())) {
return -1;
}
return this.id.compareTo(otherPerson.getId());
}
}
/**
* 工具方法,用于打印数组
*/
private void printArray(Comparable[] arr) {
if (Objects.isNull(arr) || arr.length == 0) {
return;
}
for (Comparable comparable : arr) {
System.out.println(comparable);
}
}
/**
* 冒泡排序(排序后,id从小到大)
*
* @param arr 待排序的对象数组
*/
public void bubbleSort(Comparable[] arr) {
if (Objects.isNull(arr) || arr.length == 0) {
return;
}
int length = arr.length;
for (int i = 0; i < length; i++) {
for (int j = i + 1; j < length; j++) {
if (arr[i].compareTo(arr[j]) > 0) {
Comparable tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
}
}
/**
* 选择排序(排序后,id从小到大)
*
* @param arr 待排序数组
*/
public void selectSort(Comparable[] arr) {
if (Objects.isNull(arr) || arr.length == 0) {
return;
}
int length = arr.length;
for (int i = 0; i < length; i++) {
int min = i; // min记录本轮最小值的下标
for (int j = i + 1; j < length; j++) {
if (arr[min].compareTo(arr[j]) > 0) {
min = j; // 发现更小的元素,则将min改为更小元素的下标
}
}
if (i != min) {
Comparable tmp = arr[i];
arr[i] = arr[min];
arr[min] = tmp;
}
}
}
/**
* 插入排序(排序后,id从小到大)
*
* @param arr 待排序数组
*/
public void insertSort(Comparable[] arr) {
if (Objects.isNull(arr) || arr.length == 0) {
return;
}
int length = arr.length;
for (int i = 1; i < length; i++) {
// 当前所指向的元素比他前面一个元素要小,需调整次序
if (arr[i].compareTo(arr[i - 1]) < 0) {
Comparable tmp = arr[i]; // 记录要插入的元素
int j; // j指向当前元素应该插入的位置
// 从i往前倒推,找到tmp应该插入的位置(不断将前面比tmp大的元素往后移)
for (j = i; j > 0 && tmp.compareTo(arr[j - 1]) < 0; j--) {
arr[j] = arr[j - 1];
}
arr[j] = tmp;
}
}
}
/**
* 希尔排序(排序后,id从小到大)
*
* @param arr 待排序的数组
* @param gapList 希尔排序每轮插入排序的增量(小于n的数)
*/
public void shellSort(Comparable[] arr, int[] gapList) {
if (Objects.isNull(arr) || arr.length == 0) {
return;
}
if (Objects.isNull(gapList) || gapList.length == 0) {
// 没有指定增量时,希尔排序就是插入排序,调用前面的插入排序即可
insertSort(arr);
return;
}
// 指定了增量,插入排序的变形
int gapNum = gapList.length;
int arrLength = arr.length;
for (int i = 0; i < gapNum; i++) {
int gap = gapList[i]; // 获取本轮的增量
for (int j = gap; j < arrLength; j++) {
if (arr[j].compareTo(arr[j - gap]) < 0) {
Comparable tmp = arr[j];
int k;
for (k = j; k > 0 && tmp.compareTo(arr[k - 1]) < 0; k -= gap) {
arr[k] = arr[k - gap];
}
arr[k] = tmp;
}
}
}
}
/**
* 快速排序(排序后,id从小到大)
*
* @param arr 待排序数组
* @param low 需要排序的区间低位(排序在low ~ hight进行,index从0开始)
* @param high 需要排序的区间高位(排序在low ~ hight进行, index从0开始)
*/
public void quickSort(Comparable[] arr, int low, int high) {
if (Objects.isNull(arr) || arr.length == 0 || high <= low) {
return;
}
Comparable tmp = arr[low];// tmp表示本次比较的枢纽元素
while (low < high) {
// 从右向左搜索比枢纽元素要小的元素
while (low < high && arr[high].compareTo(tmp) >= 0) {
--high;
}
// 在枢纽元素的右边遇到了比枢纽元素要小的元素,则进行交换(即使low和high指向一处)
arr[low] = arr[high];
// 从左向有搜索比枢纽元素要大的元素
while (low < high && arr[low].compareTo(tmp) <= 0) {
++low;
}
// 在枢纽元素的左边遇到了比枢纽元素要大的元素,则进行交换(即使low和high指向一处)
arr[high] = arr[low];
}
// 将枢纽元素放入(此时low和high相同)
arr[low] = tmp;
// 递归分别排序左右两部分
quickSort(arr, 0, low);
quickSort(arr, low + 1, high);
}
/**
* 归并排序(排序的最终结果在result数组中)
*
* @param arr 待排序的数组
* @param start 待排序部分的低位下标
* @param end 待排序不分的高位下标
* @param helpArr 辅助数组
*/
public void mergeSort(Comparable[] arr, int start, int end, Comparable[] helpArr) {
if (Objects.isNull(arr) || arr.length == 0 || end <= start) {
return;
}
int mid = (start + end) / 2;
// 排序左边部分
int start1 = start;
int end1 = mid;
mergeSort(arr, start1, end1, helpArr);
// 排序右边部分
int start2 = mid + 1;
int end2 = end;
mergeSort(arr, start2, end2, helpArr);
// 合并左右两部分
int mergeIndex = start;
while (start1 <= end1 && start2 <= end2) {
if (arr[start1].compareTo(arr[start2]) <= 0) {
helpArr[mergeIndex++] = arr[start1++];
} else {
helpArr[mergeIndex++] = arr[start2++];
}
}
while (start1 <= end1) {
helpArr[mergeIndex++] = arr[start1++];
}
while (start2 <= end2) {
helpArr[mergeIndex++] = arr[start2++];
}
// 将辅助数组中的元素拷贝到原数组中
for (int i = start; i <= end; i++) {
arr[i] = helpArr[i];
}
}
}
如需转载,请注明文章出处,谢谢!!!
浙公网安备 33010602011771号