package sort;
public class Sort {
final static int SIZE = 10;
public static void main(String[] args) {
int[] list = new int[SIZE];
inite(list);
System.out.print("乱序的数组:");
display(list);
// insertionSort(list);
// bubleSort(list);
// mergeSort(list);
quickSort(list);
System.out.print("排好序的数组:");
display(list);
}
// 使用随机数初始化数组
public static void inite(int[] list) {
for (int i = 0; i < list.length; i++) {
list[i] = (int) (Math.random() * 10);
}
}
// 打印数组
public static void display(int[] list) {
for (int e : list) {
System.out.print(e + " ");
}
System.out.println();
}
// 插入排序O(n²),将新的元素插入到一个有序的数组,遍历有序数组找到插入位置
public static void insertionSort(int[] list) {
for (int i = 1; i < list.length; i++) {
int temp = list[i];// 保存待插入元素
int k;
for (k = i - 1; k >= 0 && list[k] > temp; k--) {// 这里的循环条件必须是k>=0,避免k=-1时引用元素发生下标越界
list[k + 1] = list[k];
}
list[k + 1] = temp;
}
}
// 冒泡排序O(n²)、O(n),依次比较相邻元素,若不符合排序规则,则交换2个元素
public static void bubleSort(int[] list) {
boolean needNextPass = true;// 设置标志变量,若再一次循环中没有发生交换,则说明已经排好序
for (int i = 1; i < list.length && needNextPass; i++) {
needNextPass = false;// 将needNextPass初始化为false
for (int k = 0; k < list.length - i; k++) {
if (list[k] > list[k + 1]) {// 比较相邻2个元素
int temp = list[k + 1];
list[k + 1] = list[k];
list[k] = temp;
needNextPass = true;// 若发生交换,则说明还需要下一次循环排序
}
}
}
}
// 归并排序O(nlogn),递归地将一个数组划分为2个子数组,然后将子数组递归地归并为一个数组
public static void mergeSort(int[] list) {
if (list.length > 1) {// 划分一直到子数组长度为1
int[] firstHalf = new int[list.length / 2];
System.arraycopy(list, 0, firstHalf, 0, firstHalf.length);// 复制数组元素
mergeSort(firstHalf);
int[] secondHalf = new int[list.length - list.length / 2];
System.arraycopy(list, firstHalf.length, secondHalf, 0, secondHalf.length);
mergeSort(secondHalf);
merge(firstHalf, secondHalf, list);// 合并2个子数组到list数组中
}
}
// 将2个数合并到list数组中
public static void merge(int[] firstHalf, int[] secondHalf, int[] list) {
int current1 = 0;// 各自的下标
int current2 = 0;
int current3 = 0;
while (current1 < firstHalf.length && current2 < secondHalf.length) {// 循环地将2个子数组中较小的元素放入list数组中
if (firstHalf[current1] < secondHalf[current2]) {
list[current3++] = firstHalf[current1++];
} else {
list[current3++] = secondHalf[current2++];
}
}
while (current1 < firstHalf.length) {// 将剩下的元素全部放入list数组中
list[current3++] = firstHalf[current1++];
}
while (current2 < secondHalf.length) {
list[current3++] = secondHalf[current2++];
}
}
// 快速排序的辅助方法
public static void quickSort(int[] list) {
quickSort(0, list.length - 1, list);
}
// 快速排序O(nlogn)、O(n),将数组中小于主元pivot的元素放在pivot前,大于pivot的元素放在pivot后
public static void quickSort(int first, int last, int[] list) {
if (first < last) {// 循环一直持续到子数组的长度为1,因为没有创建子数组,所以这里的条件为first < last
int pivotIndex = partition(first, last, list);// 得到划分后主元pivot的位置
quickSort(first, pivotIndex - 1, list);// 递归地对pivot前的数组quickSort
quickSort(pivotIndex + 1, last, list);// 递归地对pivot后的数组quickSort
}
}
// 划分,将<主元pivot的元素放在pivot前,>pivot的元素放在pivot后,对于其中的关系符号> < >= <= 需要好好斟酌下
public static int partition(int first, int last, int[] list) {
int pivot = list[first];// 令第一个元素为主元pivot
int low = first + 1;
int high = last;
while (low < high) {// 循环一直持续到2个下标指针互相越过对方
while (list[low] <= pivot && low < high) {// 寻找第一个>pivot的元素,因为high和low在变化,所以这里也要加上条件low
// < high
low++; // 这里不会发生下标越界,所以low < high的位置可以任意放置
}
while (list[high] > pivot && low < high) {// 寻找第一个≤pivot的元素
high--;
}
if (high > low) {// 将2个找到的元素互换位置
int temp = list[high];
list[high] = list[low];
list[low] = temp;
}
}
while (high > first && list[high] > pivot) {// 将high移动到pivot应该在的位置,这个时候list[high]
// < pivot,条件必须是
high--; // list[high] >= pivot,避免pivot=list[high],导致后面交换出现问题
}
if (list[high] <= pivot) {// 如果pivot没有在应该在的位置上,则将其与应该在的位置上的元素交换,并返回high
list[first] = list[high];
list[high] = pivot;
return high;
} else {
return first;
}
}
}
几个排序算法的Java实现
最新推荐文章于 2024-04-24 16:12:51 发布