本章目录
一、上机目的
1、掌握分治法算法设计的一般思想和方法。
2、理解并掌握二分查找、归并分类、快速分类算法。
3、能熟练运用分治法求解问题。
4、实验中所准备的数据是有代表性的。
二、上机步骤
1.理解递归和分治策略的基本思想和算法示例;
2.上机输入和调试算法示例程序;
3.理解实验题的问题要求;
4.上机输入和调试自己所编的实验题程序;
5.验证并分析实验题的实验结果;
6.整理出实验报告;
三、上机内容与要求
1、将课本23页二分搜索算法改为程序,并输入不同的数据进行测试和验证。
import java.util.Scanner;
public class BinarySearch {
public static int binarySearch(int[] arr, int target) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int middle = (left + right) / 2;
if (arr[middle] == target) {
return middle;
} else if (arr[middle] < target) {
left = middle + 1;
} else {
right = middle - 1;
}
}
return -1;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入数组的大小:: ");
int size = scanner.nextInt();
int[] arr = new int[size];
System.out.println("请输入数组的元素:");
for (int i = 0; i < size; i++) {
arr[i] = scanner.nextInt();
}
System.out.print("请输入您要搜索你的目标值: ");
int target = scanner.nextInt();
int result = binarySearch(arr, target);
if (result != -1) {
System.out.println("目标值元素在数组中的位置是: " + result);
} else {
System.out.println("目标值不在索引内.");
}
}
}
2、将课本26页棋盘覆盖改为程序,并输入不同的数据测试和验证。
import java.util.Arrays;
import java.util.Scanner;
public class Chessboard {
private static int[][] board;
private static int tile = 1;
public static void cover(int tr, int tc, int dr, int dc, int size) {
if (size == 1) {
return;
}
int t = tile++;
int s = size / 2;
// 覆盖左上角子棋盘
if (dr < tr + s && dc < tc + s) {
cover(tr, tc, dr, dc, s);
} else {
board[tr + s - 1][tc + s - 1] = t;
cover(tr, tc, tr + s - 1, tc + s - 1, s);
}
// 覆盖右上角子棋盘
if (dr < tr + s && dc >= tc + s) {
cover(tr, tc + s, dr, dc, s);
} else {
board[tr + s - 1][tc + s] = t;
cover(tr, tc + s, tr + s - 1, tc + s, s);
}
// 覆盖左下角子棋盘
if (dr >= tr + s && dc < tc + s) {
cover(tr + s, tc, dr, dc, s);
} else {
board[tr + s][tc + s - 1] = t;
cover(tr + s, tc, tr + s, tc + s - 1, s);
}
// 覆盖右下角子棋盘
if (dr >= tr + s && dc >= tc + s) {
cover(tr + s, tc + s, dr, dc, s);
} else {
board[tr + s][tc + s] = t;
cover(tr + s, tc + s, tr + s, tc + s, s);
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("输入棋盘的大小:");
int size = scanner.nextInt();
System.out.print("输入棋盘缺失单元格的行: ");
int row = scanner.nextInt();
System.out.print("输入棋盘缺失单元格的列: ");
int column = scanner.nextInt();
board = new int[size][size];
board[row][column] = -1;
cover(0, 0, row, column, size);
for (int[] rowArray : board) {
System.out.println(Arrays.toString(rowArray));
}
}
}
运行效果图:
3、将课本29页合并排序和课本31页快速排序改为程序,并输入不同的数据测试和验证。
合并排序:
import java.util.Arrays;
import java.util.Scanner;
public class QuickSort {
public static void quickSort(int[] arr) { //数组为空或者数据只有一个时
if (arr == null || arr.length <= 1) {
return;
}
quickSort(arr, 0, arr.length - 1);
}
private static void quickSort(int[] arr, int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
private static int partition(int[] arr, int low, int high) {
int pivot = arr[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (arr[j] < pivot) { //交换
i++;
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
int temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return i + 1;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数组中的元素个数:");
int n = scanner.nextInt();
int[] arr = new int[n];
System.out.println("输入元素:");
for (int i = 0; i < n; i++) {
arr[i] = scanner.nextInt();
}
System.out.println("原始数据: " + Arrays.toString(arr));
quickSort(arr);
System.out.println("排列后的数据: " + Arrays.toString(arr));
}
}
快速排序:
import java.util.Arrays;
import java.util.Scanner;
public class MergeSort {
public static void mergeSort(int[] arr) {
if (arr == null || arr.length <= 1) {
return;
}
int[] temp = new int[arr.length];
mergeSort(arr, 0, arr.length - 1, temp);
}
private static void mergeSort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
int mid = (left + right) / 2;
mergeSort(arr, left, mid, temp);
mergeSort(arr, mid + 1, right, temp);
merge(arr, left, mid, right, temp);
}
}
private static void merge(int[] arr, int left, int mid, int right, int[] temp) {
int i = left;
int j = mid + 1;
int k = left;
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[k++] = arr[i++];
} else {
temp[k++] = arr[j++];
}
}
while (i <= mid) {
temp[k++] = arr[i++];
}
while (j <= right) {
temp[k++] = arr[j++];
}
for (i = left; i <= right; i++) {
arr[i] = temp[i];
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数组中的元素个数:");
int n = scanner.nextInt();
int[] arr = new int[n];
System.out.println("输入元素:");
for (int i = 0; i < n; i++) {
arr[i] = scanner.nextInt();
}
System.out.println("原始数据: " + Arrays.toString(arr));
mergeSort(arr);
System.out.println("排列后的数据: " + Arrays.toString(arr));
}
}
4、n个元素的集合{1,2,.,n }可以划分为若干个非空子集。例如,当n=4 时,集合{1,2,3,4}可以划分为15个不同的非空子集
如下:
{1},{2},{3},{4}}, {{1,2},{3},{4}},
{{1,3},{2},{4}}, {{1,4},{2},{3}},
{{2,3},{1},{4}}, {{2,4},{1},{3}},
{{3,4},{1},{2}}, {{1,2},{3,4}},
{{1,3},{2,4}}, {{1,4},{2,3}},
{{1,2,3},{4}}, {{1,2,4},{3}},
{{1,3,4},{2}}, {{2,3,4},{1}},
{{1,2,3,4}}
给定正整数n 和m,计算出n 个元素的集合{1,2,., n }可以划分为多少个不同的由m 个非空子集组成的集合。
import java.util.Scanner;
public class SetP {
public static int countSetPartitions(int n, int m) {
int[][] dp = new int[n + 1][m + 1];
for (int i = 1; i <= n; i++) {
dp[i][1] = 1;
}
for (int j = 1; j <= m; j++) {
dp[1][j] = 1;
}
for (int i = 2; i <= n; i++) {
for (int j = 2; j <= m; j++) {
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j] * j;
}
}
return dp[n][m];
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("please enter n:");
int n = in.nextInt();
System.out.println("please enter m:");
int m = in.nextInt();
System.out.println("n个元素的集合可以划分为m个非空子集的不同方式数量为:" + countSetPartitions(n, m));
}
}
运行效果图: