算法分析与设计实验一样本
《算法分析与设计》实验报告
专业: 计科班级: 日期: /04/11 成绩:
学生姓名: 学号: 指导老师:
实验单元一递归设计
一、实验题目
实验一排序
二、实验目的
熟悉java语言(或C++)的集成开发环境; 经过两种利用分治算法求解的排序算法来加深对递归设计和分治算法的理解。
三、实验内容
掌握递归算法的概念和基本思想, 分析并掌握排列问题的递归算法。对于一个序列, 使用快速排序算法和归并排序算法对其实现排序。
四、实验结果( 代码及运行结果)
(一)快速排序源代码:
public class QuickSort {
public static void main(String[] args) {
int[] data = new int[] { 5, 3, 6, 2, 1, 9, 4, 8, 7 };
print(data);
quickSort(data, 0, data.length - 1); // 调用快速排序方法
System.out.println("排序后的数组: "); // 打印输入函数
print(data);
}
/**
* 交换i、 j位置数组中的内容( 替代了新建临时变量)
*/
public static void swap(int[] data, int i, int j) {
if (i == j) {
return;
}
data[i] = data[i] + data[j];
data[j] = data[i] - data[j];
data[i] = data[i] - data[j];
}
/**
* 快速排序核心方法
*/
public static void quickSort(int[] data, int start, int end) {
if (start >= end) // 排除数组中仅有一个元素的情况
return;
// 以起始索引为分界点
int pivot = data[start];
int i = start + 1;
int j = end;
while (true) {
while (i <= end && data[i] < pivot) {
i++; // 从数组左边第二个元素开始,若小于pivot的元素, 下标加1 }
while (j > start && data[j] > pivot) {
j--; // 从数组最后一个元素开始,凡大于pivot的元素, 下标减1 }
if (i < j) {
// 经过上面的操作, data[i]大于pivot, data[j]小于pivot, 因此交换i、 j 中的内容
swap(data, i, j);
} else {
break;
}
}
swap(data, start, j);
print(data);
quickSort(data, start, j - 1); // 递归左子序列
quickSort(data, j + 1, end); // 递归右子序列
}
public static void print(int[] data) {
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + "\t");
}
System.out.println();
}
}
运行结果为:
1.1 快速排序算法运行结果
(二)归并排序源代码:
public class MergeSortTest {
// 设计count静态全局变量, 计算递归的次数
private static int count = 0;
public static void main(String[] args) {
int[] data = new int[] { 0, 0, 5, 3, 6, 2, 9, 4, 7 };
System.out.print("排序前: \t");
print(data);
mergeSort(data); // 调用归并排序方法
System.out.print("排序后: \t");
print(data);
}
/**
* 归并排序方法mergeSort
*/
public static void mergeSort(int[] data) {
sort(data, 0, data.length - 1);
}
/**
* 排序方法
*/
public static void sort(int[] data, int left, int right) {
if (left >= right) // 如果数组中只有一个元素, 则无须操作。返回空return;
int center = (left + right) / 2; // 求中间索引
sort(data, left, center); // 1、左递归
sort(data, center + 1, right); // 2、右递归
merge(data, left, center, right); // 3、合并
System.out.print("第" + (count++) + "递归\t");
print(data); // 打印输出数组
}
/**
* 归并方法, 归并前面2个数组已有序, 归并后依然有序
*
* @param data 数组对象
* @param left 左数组的第一个元素的索引
* @param center 左数组的最后一个元素的索引, center+1是右数组第一个元素的索引 * @param right 右数组最后一个元素的索引
*/
public static void merge(int[] data, int left, int center, int right) { int[] temp = new int[data.length]; // 经过new关键字, 在堆上创立临时数组
int middle = center + 1; // 右数组第一个元素索引
int k = left; // k记录临时数组的索引
int tmp = left; // 缓存左数组第一个元素的索引
while (left <= center && middle <= right) {
if (data[left] <= data[middle]) { // 从两个数组中取出最小的放入临时数组
temp[k++] = data[left++];
} else {
temp[k++] = data[middle++];
}
}
while (middle <= right) { // 剩余部分依次放入临时数组( 实际上两个while只会执行其中一个)
temp[k++] = data[middle++];
}
while (left <= center) {
temp[k++] = data[left++];
}
while (tmp <= right) { // 将临时数组中的内容拷贝回原数组中
data[tmp] = temp[tmp++];
}
}
public static void print(int[] data) {
for (int i = 0; i < data.length; i++) {
System.out.print(data[i] + "\t");
}
System.out.println();}}