(注:实验一请同学们自主学习完成,以下代码仅供参考)
实验目的
- 探索不同排序算法在不同数据量下的时间效率
- 探索排序算法的稳定性
- 掌握快速排序partition的双指针算法
- 掌握归并排序的合并算法
代码示例
import java.util.Scanner;
// 排序算法解决方案: SortingSolution
public class SortingSolution {
// 比较两个数组元素大小
int comp(int a, int b) { return Integer.compare(a, b); }
// 交换数组元素
void swap(int[] a, int i, int j) { int temp = a[i]; a[i] = a[j]; a[j] = temp; }
// 1. 冒泡排序
void bubbleSort(int[] a) {
int bound, exchange = a.length - 1;
while (exchange != 0) {
bound = exchange;
exchange = 0;
for (int i = 0; i < bound; i++)
if (comp(a[i], a[i + 1]) > 0) {
swap(a, i, i + 1);
exchange = i;
}
}
}
// 2. 选择排序
void selectSort(int[] a) {
for (int i = 0; i < a.length - 1; i++) {
int index = i;
for (int j = i + 1; j < a.length; j++)
if (comp(a[j], a[index]) < 0)
index = j;
if (index != i)
swap(a, i, index);
}
}
// 3. 插入排序
void insertSort(int[] a) {
for (int i = 1; i < a.length; i++) {// 从第 2 个记录开始执行
int t = a[i], j = i - 1; // 将待插入元素暂存于变量 t
for (; j >= 0 && t < a[j]; j--) // 搜索插入位置,注意不要越界
a[j + 1] = a[j]; // 记录后移
a[j + 1] = t; // 完成 t 的插入操作
}
}
// 4. 归并排序
int[] mergeSort(int[] a, int left, int right) {
// 边界条件:没有元素或 1 个元素直接返回
if (left > right) return new int[0];
if (left == right) return new int[] { a[left] };
// 划分并求解子问题
int mid = left + (right - left) / 2;
int[] a1 = mergeSort(a, left, mid);
int[] a2 = mergeSort(a, mid + 1, right);
// 合并
int[] c = new int[a1.length + a2.length];
int i1 = 0, i2 = 0;
while (i1 < a1.length && i2 < a2.length) {
if (a1[i1] <= a2[i2]) {
c[i1 + i2] = a1[i1];
i1++;
} else {
c[i1 + i2] = a2[i2];
i2++;
}
}
// 不要忘记对子数组的剩余部分进行合并
while (i1 < a1.length) {
c[i1 + i2] = a1[i1];
i1++;
}
while (i2 < a2.length) {
c[i1 + i2] = a2[i2];
i2++;
}
return c;
}
// 5. 快速排序
void quickSort(int[] a, int p, int r) {
if (p < r) {
int q = partition(a, p, r); // 划分,并返回轴值在数组中的位置
quickSort(a, p, q - 1); // 递归求解左子数组
quickSort(a, q + 1, r); // 递归求解右子数组
}
}
// (快速排序核心算法)对 a[p..r] 进行划分操作
int partition(int[] a, int p, int r) {
int pivot = a[p]; // 选定轴值
int i = p, j = r; // 初始化左右指针
while (i < j) {
while (i < j && pivot <= a[j])
j--;
if (i < j) {
swap(a, i, j);
i++;
}
while (i < j && pivot >= a[i])
i++;
if (i < j) {
swap(a, i, j);
j--;
}
}
return i;
}
// 测试:应用排序算法对序列进行排序
int[] testSort(int[] a, int select) {
// 调用其中一种排序算法:
switch (select) {
case 1:
bubbleSort(a); // 冒泡排序
break;
case 2:
selectSort(a); // 选择排序
break;
case 3:
insertSort(a); // 插入排序
break;
case 4:
a = mergeSort(a, 0, a.length - 1); // 归并排序
break;
case 5:
quickSort(a, 0, a.length - 1); // 快速排序
break;
default:
System.out.println("不存在选项为" + select + "的排序算法!");
a = new int[] { -1 };
}
return a;
}
// 打印数组到输出终端
static String display(int[] a, int i) {
return i == a.length - 1 ? "" + a[i]:
String.format("%d\t%s", a[i], display(a, i + 1));
}
public static void main(String[] args) {
System.out.println("1.冒泡排序 2.选择排序 3.插入排序 4.归并排序 5.快速排序");
System.out.print("请选择排序算法(1-5): ");
Scanner scan = new Scanner(System.in);
int s = scan.nextInt();
scan.close();
int[] a = { 49, 12, 54, 96, 26, 37, 48, 64 };
System.out.println("排序前:" + display(a, 0));
SortingSolution sln = new SortingSolution();
a = sln.testSort(a, s);
System.out.println("排序后:" + display(a, 0));
}
}