1、题目要求
本次实验拟解决生活中最常见的问题之一:检索问题(查找问题),该问题要求在一个列表中查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1。根据列表中元素的相对大小信息,有顺序检索、二分检索、三分检索等算法思路可供参考使用,本次实验需要学生根据所给列表的性质采取有效算法解决相关问题,并能分析各个算法所使用的算法设计技术和时间复杂度。下列基本要求必须完成:
1、设计一个交互界面(例如菜单)供用户选择,如果可能,最好是一个图形化用户界面;
2、能够人工输入或随机产生一个长度为n的整数数组,要求数组任意两个元素都互不相同;
3、设计一个算法判断要求2中产生的整数数组是否为或未排序(输出0)、升序(输出1)、降序(输出2)、先升后降(输出3)、或先降后升(输出4)状态;
4、给定某具体元素,使用顺序检索算法判断该具体元素是否出现在要求2中产生的数组中,并统计关键字比较的次数;
5、给定某具体元素,使用二分检索算法判断该具体元素是否出现在要求2中产生的升序或降序的数组中,并统计关键字比较的次数;
6、给定某具体元素,使用三分检索算法判断该具体元素是否出现在要求2中产生的升序或降序的数组中,并统计关键字比较的次数;
7、给定先升后降(或先降后升)数组,使用二分检索思路查找该数组的最大值(或最小值),并统计关键字比较的次数。
附加:给定某具体元素,使用二分检索算法判断该具体元素是否出现在要求2中产生的升序或降序的数组中,若出现,返回具体元素所在的位置,否则,返回小于最接近该具体元素的位置。
2、具体实现
阉割版
package com.exp2;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;import java.util.Arrays;import java.util.Scanner;/*** @author 郑万富* @className ArraySearch* @date 2021/11/22 12:33*/@Data@NoArgsConstructor@AllArgsConstructorpublic class ArraySearch {private int[] data;public static void main(String[] args) {ArraySearch search = new ArraySearch();search.choice();}public void miniMenu() {System.out.println("|----------实验2:检索算法的实现--------|");System.out.println(" 1.手动初始化数组");System.out.println(" 2.随机初始化数组");System.out.println(" 3.数组排序状态");System.out.println(" 4.顺序检索算法");System.out.println(" 5.二分检索算法");System.out.println(" 6.三分检索算法");System.out.println(" 7.二分法查找最值");System.out.println(" 8.附加题验证");System.out.println(" 9.返回主菜单");System.out.println(" 0.退出程序");System.out.println("|-----------------------------------|");}public void MoreMenu() {System.out.println("|------------------------------------------------------实验2:检索算法的实现----------------------------------------------------------|");System.out.println(" 1.设计一个交互界面(例如菜单)供用户选择,如果可能,最好是一个图形化用户界面");System.out.println(" 2.能够人工输入或随机产生一个长度为n的整数数组,要求数组任意两个元素都互不相同");System.out.println(" 3.设计一个算法判断要求2中产生的整数数组是否为或未排序(输出0)、升序(输出1)、降序(输出2)、先升后降(输出3)、或先降后升(输出4)状态;");System.out.println(" 4.给定某具体元素,使用顺序检索算法判断该具体元素是否出现在要求2中产生的数组中,并统计关键字比较的次数;");System.out.println(" 5.给定某具体元素,使用二分检索算法判断该具体元素是否出现在要求2中产生的升序或降序的数组中,并统计关键字比较的次数;");System.out.println(" 6.给定某具体元素,使用三分检索算法判断该具体元素是否出现在要求2中产生的升序或降序的数组中,并统计关键字比较的次数;");System.out.println(" 7.给定先升后降(或先降后升)数组,使用二分检索思路查找该数组的最大值(或最小值),并统计关键字比较的次数。");System.out.println(" 8.给定某具体元素,使用二分检索算法判断该具体元素是否出现在要求2中产生的升序或降序的数组中,若出现,返回具体元素所在的位置,否则,返回小于最接近该具体元素的位置。");System.out.println("|---------------------------------------------------------------------------------------------------------------------------------|");}public void choice() {Scanner sc = new Scanner(System.in);ArraySearch array = new ArraySearch();while (true) {miniMenu();System.out.println("请输入你要执行的序号(0退出):");int choice = sc.nextInt();switch (choice) {case 1:array.setData(array.makeArray());continue;case 2:array.setData(array.makeArrayRandom());continue;case 3:int result = array.isSorted(array.getData());System.out.println(result);continue;case 4:System.out.println("请输入查找元素:");int num1 = sc.nextInt();System.out.println("关键字比较的次数:" + array.SequentialSearch(array.getData(), num1));continue;case 5:System.out.println("请输入查找元素:");int num2 = sc.nextInt();System.out.println("关键字比较的次数:" + array.BinarySearch(array.getData(), num2));continue;case 6:System.out.println("请输入查找元素:");int num3 = sc.nextInt();int index=array.threePointSearch(array.getData(), num3);System.out.println("索引位置" + index);if (index != -1) {System.out.println("查找成功");} else {System.out.println("查找失败");}continue;case 7:System.out.println("比较次数:" + array.binarySearchFindMaxAndMin(array.getData()));continue;case 8:System.out.println("请输入查找元素:");int num5 = sc.nextInt();System.out.println("最接近元素:");array.binarySearchFindClose(array.getData(), array.getData().length, num5, 0, array.getData().length);continue;case 9:MoreMenu();continue;case 0:System.out.println("正在退出程序...");break;default:System.out.println("输入错误,请重新输入:");continue;}break;}}//2、能够人工输入或随机产生一个长度为n的整数数组,要求数组任意两个元素都互不相同;public int[] makeArray() {Scanner sc = new Scanner(System.in);System.out.println("请输入数组长度:");int n = sc.nextInt();int[] array = new int[n];for (int i = 0; i < array.length; i++) {System.out.println("请输入数组第" + (i + 1) + "个元素:");array[i] = sc.nextInt();}System.out.println("数组为:" + Arrays.toString(array));return array;}public int[] makeArrayRandom() {Scanner sc = new Scanner(System.in);System.out.println("请输入数组长度:");int n = sc.nextInt();int[] array = new int[n];for (int i = 0; i < array.length; i++) {// System.out.println("请输入数组第" + (i + 1) + "个元素:");array[i] = (int) (Math.random() * 100);}System.out.println("数组为:" + Arrays.toString(array));return array;}//3、设计一个算法判断要求2中产生的整数数组是否为或未排序(输出0)、升序(输出1)、降序(输出2)、先升后降(输出3)、或先降后升(输出4)状态;public int isSorted(int[] arr) {//升序的个数,降序的个数int up_flag = 0, down_flag = 0;//是第一次升序还是降序boolean first_up = false, first_down = false;//用来判断数组中是否会出现多次波动。例如同时存在波峰和波底boolean flag = false;for (int i = 0; i < arr.length - 1; i++) {//判断第一个元素开始是升序还是降序(为了后面判断方便)if (!first_down && !first_up) {if (arr[i] < arr[i + 1]) {up_flag++;first_up = true;} else {first_down = true;down_flag++;}} else {//若是一开始降序的话,就只能为三种选项(无序,降序,先降后生)if (first_down) {if (arr[i] > arr[i + 1]) {down_flag++;//在下面代码中是升序才将flag置true,所以如果进入了升序再进入了降序判断代码,一定无序if (flag) {System.out.println("无序");return 0;}} else {if (!flag) {flag = true;}up_flag++;}} else if (first_up) {if (arr[i] < arr[i + 1]) {up_flag++;if (flag) {System.out.println("无序");return 0;}} else {if (!flag) {down_flag++;flag = true;}}}}}//此处可以不考虑无序,因为如果无序已经在for循环中return了if (down_flag == 0) {//若不存在降的元素,那只能是升序System.out.println("升序");return 1;} else if (up_flag == 0) {//若不存在升的元素,那只能是降序System.out.println("降序");return 2;} else if (first_down && up_flag != 0) {//若一开始为降,且升序元素不为0,说明绝对有波底System.out.println("先降后升");return 4;} else if (first_up && down_flag != 0) {//若一开始为升,且降序元素不为0,说明绝对有波峰System.out.println("先升后降");return 3;}return -1;}//4、给定某具体元素,使用顺序检索算法判断该具体元素是否出现在要求2中产生的数组中,并统计关键字比较的次数;public int SequentialSearch(int[] data, int target) {int count = 0;for (int i = 0; i < data.length; i++) {count++;if (target == data[i]) {System.out.println("该具体元素出现在要求2中产生的数组中");return count;} else {continue;// System.out.println("该具体元素没有出现在要求2中产生的数组中");}}System.out.println("该具体元素没有出现在要求2中产生的数组中");return count;}//5、给定某具体元素,使用二分检索算法判断该具体元素是否出现在要求2中产生的升序或降序的数组中,并统计关键字比较的次数;public int BinarySearch(int[] data, int target) {int flag = isSorted(data);int count = 0;if (flag == 1 || flag == 2) {System.out.println("该具体元素出现在要求2中产生的升序或降序的数组中");int l = 0, r = data.length - 1, mid;while (l <= r) {count++;//中间点mid = (l + r) >>> 1;if (target == data[mid]) {System.out.println("索引值:" + mid);return mid;} else if (target < data[mid]) {r = mid - 1;} else {l = mid + 1;}}} else {System.out.println("该具体元素没有出现在要求2中产生的升序或降序的数组中");}return count;}//逆序数组public static void reverse(int[] arr, int len) {int i, j, tmp, m;m = (len - 1) / 2;//结束的标志;for (i = 0; i <= m; i++) {j = len - 1 - i;tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}}//给定某具体元素,使用三分检索算法判断该具体元素是否出现在要求2中产生的升序或降序的数组中,并统计关键字比较的次数;public int threePointSearch(int[] temp, int key) {int flag = isSorted(data);System.out.println("flag:" + flag);int count = 0;int low = 0;int high = temp.length - 1;int mid1;int mid2;if (flag == 1) {//升序数组if (temp[low] > key || temp[high] < key || low > high) {return -1;}while (low <= high) {mid1 = 1 + (low + high) / 3;mid2 = 1 + (low + high) * 2 / 3;if (temp[low] == key) {return low;}if (temp[high] == key) {return high;}if (temp[mid1] == key) {return mid1;}if (temp[mid2] == key) {return mid2;}if (key < temp[mid1]) {high = mid1 - 1;}if (key > temp[mid2]) {low = mid2 + 1;}if (key > temp[mid1] && key < temp[mid2]) {low = mid1 + 1;high = mid2 - 1;}}} else if (flag == 2) {//降序数组if (temp[low] < key || temp[high] > key || low > high) {return -1;}reverse(temp, temp.length);int index1 = 0;System.out.println("反转数组:" + Arrays.toString(temp));for (int i = 0; i < temp.length; i++) {if (key == temp[i]) {index1 = i;}}System.out.println("index1:" + index1);while (low <= high) {mid1 = 1 + (low + high) / 3;mid2 = 1 + (low + high) * 2 / 3;if (temp[low] == key) {break;// return low ;}if (temp[high] == key) {break;// return high ;}if (temp[mid1] == key) {break;// return mid1 ;}if (temp[mid2] == key) {break;// return mid2 ;}if (key < temp[mid1]) {high = mid1 - 1;}if (key > temp[mid2]) {low = mid2 + 1;}if (key > temp[mid1] && key < temp[mid2]) {low = mid1 + 1;high = mid2 - 1;}}reverse(temp, temp.length);int index2 = 0;System.out.println("还原数组:" + Arrays.toString(temp));index2 = temp.length - index1 - 1;System.out.println("index2:" + index2);for (int i = 0; i < temp.length; i++) {count++;if (i == index2) {System.out.println("在数组中找到值:" + temp[i]);System.out.println("比较次数2:" + count);return index2;}}} else {System.out.println("不属于升序或降序的数组类型!");return -1;}return -1;}//7、给定先升后降(或先降后升)数组,使用二分检索思路查找该数组的最大值(或最小值),并统计关键字比较的次数。public static int getMax(int[] array) {int max = array[0];int i = 0;for (i = 0; i < array.length; i++) {if (array[i] >= max) {max = array[i];}}return max;}public static int getMin(int[] array) {int mix = array[0];int i = 0;for (i = 0; i < array.length; i++) {if (array[i] < mix) {mix = array[i];}}return mix;}public int binarySearchFindMaxAndMin(int[] data) {int flag = isSorted(data);int max = 0;int min = 0;int count = 0;if (flag == 3) {System.out.println("最值元素出现在要求2中产生的先升后降(或先降后升)数组中");max = getMax(data);int l = 0, r = data.length - 1, mid = 0;while (l <= r) {count++;mid = (l + r) >>> 1;if (max == data[mid]) {System.out.println("最大值:" + max);return count;} else if (max < data[mid]) {r = mid - 1;} else {l = mid + 1;}}} else if (flag == 4) {//先降后升System.out.println("最值元素出现在要求2中产生的先升后降(或先降后升)数组中");min = getMin(data);int l = 0, r = data.length - 1, mid = 0;while (l <= r) {count++;mid = (l + r) >>> 1;if (min == data[mid]) {System.out.println("最小值:" + min);return count;} else if (min < data[mid]) {l = mid + 1;} else {r = mid - 1;}}} else {System.out.println("最值元素没有出现在要求2中产生的先升后降(或先降后升)数组中");}// System.out.println("比较次数:" + count);return count;}//附加:给定某具体元素,使用二分检索算法判断该具体元素是否出现在要求2中产生的升序或降序的数组中,若出现,返回具体元素所在的位置,否则,返回小于最接近该具体元素的位置。public int binarySearchFindClose(int a[], int n, int target, int i, int j) {int left = 0;int right = n - 1;int mid;while (left <= right) {mid = (left + right) / 2;if (target == a[mid]) {i = mid;j = mid;System.out.println(a[mid]);System.out.println("索引值:" + mid);return mid;} else if (target > a[mid]) {left = mid + 1;} else {right = mid - 1;}}i = right;j = left;if (i < 0) {System.out.println(a[0]);System.out.println("最接近索引值:" + 0);} else if (j >= n) {System.out.println(a[n - 1]);} else {int l = (target - a[i]) > 0 ? (target - a[i]) : (-(target - a[i]));int r = (target - a[j]) > 0 ? (target - a[j]) : (-(target - a[j]));if (l < r) {System.out.println(a[n]);System.out.println("最接近索引值:" + n);} else if (l == r) {System.out.println(a[i]);System.out.println("最接近索引值:" + i);} else {System.out.println(a[i]);System.out.println("最接近索引值:" + i);}}return -1;}}
3. 验证程序所有功能
升序
请输入查找元素:3|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):1请选择初始化数组方式(1.手动初始化 2.随机初始化)1请输入数组长度:81 3 5 7 9 11 12 13数组为:[1, 3, 5, 7, 9, 11, 12, 13]|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):21|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):3查找元素target:3比较次数:21|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):4查找元素target:3比较次数:21|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):5查找元素target:31|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):6查找元素target:3数组类型不是3或4-1|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):7请输入附加题查找元素:12126|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):0输入错误,正在退出...Process finished with exit code 0
降序
请输入查找元素:6|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):1请选择初始化数组方式(1.手动初始化 2.随机初始化)1请输入数组长度:99 8 7 6 5 4 3 2 1数组为:[9, 8, 7, 6, 5, 4, 3, 2, 1]|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):22|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):3查找元素target:6比较次数:43|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):4查找元素target:6比较次数:43|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):5查找元素target:6反转数组:[1, 2, 3, 4, 5, 6, 7, 8, 9]对称位置:5还原数组:[9, 8, 7, 6, 5, 4, 3, 2, 1]真实位置:3比较次数:43|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):6查找元素target:6数组类型不是3或4-1|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):7请输入附加题查找元素:445|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):0输入错误,正在退出...Process finished with exit code 0
先升后降
请输入查找元素:6|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):1请选择初始化数组方式(1.手动初始化 2.随机初始化)1请输入数组长度:101 3 5 7 9 8 6 4 2 0数组为:[1, 3, 5, 7, 9, 8, 6, 4, 2, 0]|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):23|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):3查找元素target:6比较次数:76|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):4查找元素target:6-1|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):5查找元素target:6-1|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):6查找元素target:6比较次数1最大值:9位置:4|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):7请输入附加题查找元素:5-1|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):0输入错误,正在退出...Process finished with exit code 0
先降后升
请输入查找元素:3|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):1请选择初始化数组方式(1.手动初始化 2.随机初始化)1请输入数组长度:1010 8 6 4 2 1 3 5 7 9数组为:[10, 8, 6, 4, 2, 1, 3, 5, 7, 9]|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):24|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):3查找元素target:3比较次数:76|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):4查找元素target:3-1|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):5查找元素target:3-1|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):6查找元素target:3数组类型不是3或4-1|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):7请输入附加题查找元素:4-1|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):0输入错误,正在退出...Process finished with exit code 0
无序
请输入查找元素:5|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):1请选择初始化数组方式(1.手动初始化 2.随机初始化)2请输入数组长度:10数组为:[32, 45, 65, 5, 75, 85, 18, 70, 46, 27]|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):20|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):3查找元素target:5比较次数:43|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):4查找元素target:5-1|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):5查找元素target:5-1|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):6查找元素target:5数组类型不是3或4-1|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):7请输入附加题查找元素:5-1|************--实验2:检索算法的实现--***************|* 1.初始数组数据 ** 2.判断数组状态 ** 3.顺序检索算法 ** 4.二分检索算法 ** 5.三分检索算法 ** 6.二分查找最值 ** 7.附加题目验证 ** 0.主动退出程序 *|************************************************|------------------------------------By->2021-11-24PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)请输入你要执行的序号(0退出):0输入错误,正在退出...Process finished with exit code 0
实现代码
package com.exp2.hetong;import java.util.Arrays;import java.util.Scanner;/*** @author SearchAlgorithm*/public class SearchAlgorithm {private int[] SearchArray;public int[] getSearchArray() {return SearchArray;}public void setSearchArray(int[] searchArray) {SearchArray = searchArray;}public static void main(String[] args) {SearchAlgorithm SearchAlgorithm = new SearchAlgorithm();SearchAlgorithm.menu();}public void menu() {Scanner sc = new Scanner(System.in);SearchAlgorithm SearchAlgorithm = new SearchAlgorithm();System.out.println("请输入查找元素:");int target = sc.nextInt();while (true) {System.out.println("|************--实验2:检索算法的实现--***************|");System.out.println(" * 1.初始数组数据 *");System.out.println(" * 2.判断数组状态 *");System.out.println(" * 3.顺序检索算法 *");System.out.println(" * 4.二分检索算法 *");System.out.println(" * 5.三分检索算法 *");System.out.println(" * 6.二分查找最值 *");System.out.println(" * 7.附加题目验证 *");System.out.println(" * 0.主动退出程序 *");System.out.println("|************************************************|");System.out.println("------------------------------------By->2021-11-24");System.out.println("PS:查找某个具体元素是否出现,若出现,返回具体元素在数组中的位置,否则返回-1(方法2除外)");System.out.println("请输入你要执行的序号(0退出):");int choice = sc.nextInt();switch (choice) {case 1:System.out.println("请选择初始化数组方式(1.手动初始化\t2.随机初始化)");int take = sc.nextInt();if (take == 1) {SearchAlgorithm.setSearchArray(initArrayByHand());} else if (take == 2) {SearchAlgorithm.setSearchArray(initArrayByRandom());} else {System.out.println("输入错误,返回菜单");}continue;case 2:System.out.println(isSorted(SearchAlgorithm.getSearchArray()));continue;case 3:System.out.println("查找元素target:" + target);System.out.println(SequentialSearch(SearchAlgorithm.getSearchArray(), target));continue;case 4:System.out.println("查找元素target:" + target);System.out.println(BinarySearch(SearchAlgorithm.getSearchArray(), target));continue;case 5:System.out.println("查找元素target:" + target);System.out.println(threePointSearch(SearchAlgorithm.getSearchArray(), target));continue;case 6:System.out.println("查找元素target:" + target);System.out.println(binarySearchFindMaxAndMin(SearchAlgorithm.getSearchArray()));continue;case 7:System.out.println("请输入附加题查找元素:");int find = sc.nextInt();System.out.println(binarySearchFindClose(SearchAlgorithm.getSearchArray(), SearchAlgorithm.getSearchArray().length, find, 0, SearchAlgorithm.getSearchArray().length));continue;default:System.out.println("输入错误,正在退出...");break;}break;}}//2、能够人工输入或随机产生一个长度为n的整数数组,要求数组任意两个元素都互不相同;public int[] initArrayByHand() {Scanner sc = new Scanner(System.in);System.out.println("请输入数组长度:");int n = sc.nextInt();int[] array = new int[n];for (int i = 0; i < array.length; i++) {array[i] = sc.nextInt();}System.out.println("数组为:" + Arrays.toString(array));return array;}public int[] initArrayByRandom() {Scanner sc = new Scanner(System.in);System.out.println("请输入数组长度:");int n = sc.nextInt();int[] array = new int[n];for (int i = 0; i < array.length; i++) {// System.out.println("请输入数组第" + (i + 1) + "个元素:");array[i] = (int) (Math.random() * 100);}System.out.println("数组为:" + Arrays.toString(array));return array;}//3、设计一个算法判断要求2中产生的整数数组是否为或未排序(输出0)、升序(输出1)、降序(输出2)、先升后降(输出3)、或先降后升(输出4)状态;public int isSorted(int[] arr) {//升序的个数,降序的个数int up_flag = 0, down_flag = 0;//是第一次升序还是降序boolean first_up = false, first_down = false;//用来判断数组中是否会出现多次波动。例如同时存在波峰和波底boolean flag = false;for (int i = 0; i < arr.length - 1; i++) {//判断第一个元素开始是升序还是降序(为了后面判断方便)if (!first_down && !first_up) {if (arr[i] < arr[i + 1]) {up_flag++;first_up = true;} else {first_down = true;down_flag++;}} else {//若是一开始降序的话,就只能为三种选项(无序,降序,先降后生)if (first_down) {if (arr[i] > arr[i + 1]) {down_flag++;//在下面代码中是升序才将flag置true,所以如果进入了升序再进入了降序判断代码,一定无序if (flag) {return 0;}} else {if (!flag) {flag = true;}up_flag++;}} else if (first_up) {if (arr[i] < arr[i + 1]) {up_flag++;if (flag) {return 0;}} else {if (!flag) {down_flag++;flag = true;}}}}}//此处可以不考虑无序,因为如果无序已经在for循环中return了if (down_flag == 0) {//若不存在降的元素,那只能是升序return 1;} else if (up_flag == 0) {//若不存在升的元素,那只能是降序return 2;} else if (first_down && up_flag != 0) {//若一开始为降,且升序元素不为0,说明绝对有波底return 4;} else if (first_up && down_flag != 0) {//若一开始为升,且降序元素不为0,说明绝对有波峰return 3;}return -1;}//4、给定某具体元素,使用顺序检索算法判断该具体元素是否出现在要求2中产生的数组中,并统计关键字比较的次数;public int SequentialSearch(int[] Searcharray, int target) {int count = 0;for (int i = 0; i < Searcharray.length; i++) {count++;if (target == Searcharray[i]) {System.out.println("比较次数:" + count);return i;}}return -1;}//5、给定某具体元素,使用二分检索算法判断该具体元素是否出现在要求2中产生的升序或降序的数组中,并统计关键字比较的次数;public int BinarySearch(int[] Searcharray, int target) {int flag = isSorted(Searcharray);int count = 0;//升序数组if (flag == 1 ) {int l = 0;int r = Searcharray.length - 1;int mid;while (l <= r) {count++;//中间点mid = (l + r) >>> 1;if (target == Searcharray[mid]) {System.out.println("比较次数:" + count);return mid;} else if (target < Searcharray[mid]) {r = mid - 1;} else {l = mid + 1;}}//处理降序数组}else if(flag==2){int l = 0;int r = Searcharray.length - 1;int mid;while (l <= r) {count++;//中间点mid = (l + r) >>> 1;if (target == Searcharray[mid]) {System.out.println("比较次数:" + count);return mid;} else if (target < Searcharray[mid]) {l = mid + 1;} else {r = mid - 1;}}}return -1;}//逆序数组public static void reverse(int[] arr, int len) {int i;int j;int tmp;int m;m = (len - 1) / 2;//结束的标志;for (i = 0; i <= m; i++) {j = len - 1 - i;tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}}//给定某具体元素,使用三分检索算法判断该具体元素是否出现在要求2中产生的升序或降序的数组中,并统计关键字比较的次数;public int threePointSearch(int[] temp, int key) {int flag = isSorted(temp);int count = 0;int low = 0;int high = temp.length - 1;int mid1;int mid2;if (flag == 1) {//升序数组if (temp[low] > key || temp[high] < key) {return -1;}while (low <= high) {mid1 = 1 + (low + high) / 3;mid2 = 1 + (low + high) * 2 / 3;if (temp[low] == key) {return low;}if (temp[high] == key) {return high;}if (temp[mid1] == key) {return mid1;}if (temp[mid2] == key) {return mid2;}if (key < temp[mid1]) {high = mid1 - 1;}if (key > temp[mid2]) {low = mid2 + 1;}if (key > temp[mid1] && key < temp[mid2]) {low = mid1 + 1;high = mid2 - 1;}}} else if (flag == 2) {//降序数组if (temp[low] < key || temp[high] > key || low > high) {return -1;}reverse(temp, temp.length);int index1 = 0;System.out.println("反转数组:" + Arrays.toString(temp));for (int i = 0; i < temp.length; i++) {if (key == temp[i]) {index1 = i;}}System.out.println("对称位置:" + index1);while (low <= high) {mid1 = 1 + (low + high) / 3;mid2 = 1 + (low + high) * 2 / 3;if (temp[low] == key) {break;// return low ;}if (temp[high] == key) {break;// return high ;}if (temp[mid1] == key) {break;// return mid1 ;}if (temp[mid2] == key) {break;// return mid2 ;}if (key < temp[mid1]) {high = mid1 - 1;}if (key > temp[mid2]) {low = mid2 + 1;}if (key > temp[mid1] && key < temp[mid2]) {low = mid1 + 1;high = mid2 - 1;}}reverse(temp, temp.length);int index2 = 0;System.out.println("还原数组:" + Arrays.toString(temp));index2 = temp.length - index1 - 1;System.out.println("真实位置:" + index2);for (int i = 0; i < temp.length; i++) {count++;if (i == index2) {System.out.println("比较次数:" + count);return index2;}}}return -1;}//7、给定先升后降(或先降后升)数组,使用二分检索思路查找该数组的最大值(或最小值),并统计关键字比较的次数。public static int getMax(int[] array) {int max = array[0];int i;for (i = 0; i < array.length; i++) {if (array[i] >= max) {max = array[i];}}return max;}public static int getMin(int[] array) {int mix = array[0];int i;for (i = 0; i < array.length; i++) {if (array[i] < mix) {mix = array[i];}}return mix;}public int binarySearchFindMaxAndMin(int[] Searcharray) {int flag = isSorted(Searcharray);int max = 0;int min = 0;int count = 0;if (flag == 3) {max = getMax(Searcharray);int l = 0;int r = Searcharray.length - 1;int mid = 0;while (l <= r) {count++;mid = (l + r) >>> 1;if (max == Searcharray[mid]) {System.out.println("比较次数" + count);System.out.println("最大值:" + max + "位置:");return mid;} else if (max < Searcharray[mid]) {r = mid - 1;} else {l = mid + 1;}}} else if (flag == 4) {//先降后升min = getMin(Searcharray);int l = 0;int r = Searcharray.length - 1;int mid = 0;while (l <= r) {count++;mid = (l + r) >>> 1;if (min == Searcharray[mid]) {System.out.println("比较次数:" + count);System.out.println("最小值:" + min + "位置:");return mid;} else if (min < Searcharray[mid]) {l = mid + 1;} else {r = mid - 1;}}}System.out.println("数组类型不是3或4");return -1;}//附加:给定某具体元素,使用二分检索算法判断该具体元素是否出现在要求2中产生的升序或降序的数组中,若出现,返回具体元素所在的位置,否则,返回小于最接近该具体元素的位置。public int binarySearchFindClose(int a[], int n, int target, int i, int j) {int flag=isSorted(a);//处理升序if (flag==1){int left = 0;int right = n - 1;int mid;while (left <= right) {mid = (left + right) / 2;if (target == a[mid]) {i = mid;j = mid;System.out.println(a[mid]);return mid;} else if (target > a[mid]) {left = mid + 1;} else {right = mid - 1;}}i = right;j = left;if (i < 0) {System.out.println(a[0]);System.out.println("最接近索引值:" + 0);} else if (j >= n) {System.out.println(a[n - 1]);} else {int l = (target - a[i]) > 0 ? (target - a[i]) : (-(target - a[i]));int r = (target - a[j]) > 0 ? (target - a[j]) : (-(target - a[j]));if (l < r) {System.out.println(a[n]);System.out.println("最接近索引值:" + n);} else if (l == r) {System.out.println(a[i]);System.out.println("最接近索引值:" + i);} else {System.out.println(a[i]);System.out.println("最接近索引值:" + i);}}}else if(flag==2){int left = 0;int right = n - 1;int mid;while (left <= right) {mid = (left + right) / 2;if (target == a[mid]) {i = mid;j = mid;System.out.println(a[mid]);return mid;} else if (target > a[mid]) {right = mid - 1;} else {left = mid + 1;}}i = right; //大-->小值索引j = left; //小-->大值做因if (j < 0) {System.out.println(a[0]);System.out.println("最接近索引值:" + 0);} else if (i >= n) {System.out.println(a[n - 1]);} else {int l = (target - a[j]) > 0 ? (target - a[j]) : (-(target - a[j]));int r = (target - a[i]) > 0 ? (target - a[i]) : (-(target - a[i]));if (l < r) {System.out.println(a[0]);System.out.println("最接近索引值:" + 0);} else if (l == r) {System.out.println(a[j]);System.out.println("最接近索引值:" + j);} else {System.out.println(a[j]);System.out.println("最接近索引值:" + j);}}}return -1;}}
