07-冒泡排序、二分查找、图书管理系统
1、冒泡排序
-
思路
- 相邻元素比较
-
demo
-
import java.util.Arrays; import java.util.Random; import java.util.Scanner; public class BubbleSort { public static void main(String[] args) { // 随机生成(1-100)的指定长度的数组 Scanner scanner = new Scanner(System.in); System.out.print("请输入指定的数组长度:"); int[] arr = randomArr(scanner.nextInt()); System.out.println("源数组: arr = " + Arrays.toString(arr)); bubbleSort(arr); System.out.println("---------------------------------"); System.out.println("冒泡排序后的数组为:arr = " + Arrays.toString(arr)); } private static void bubbleSort(int[] arr) { /* 冒泡排序原理: 每一轮排序,从第一个开始,两两比较,大的放后面 每一次比较结束后,指针往后移动一位 */ // 排序的最大轮数为 arr.length - 1,即长度为4的最大排序轮数为3轮 for (int i = 0; i < arr.length - 1; i++) { System.out.println("----------当前为第[" + (i + 1) + "]轮排序----------"); // 每次比较次数,跟轮数有关,每一轮排序结束后,需要比较的数字都会 -1 // 又因为第一次比较的次数为 arr.length - 1 // 所以可以得出规律 每次比较的次数为 arr.length - 1 - i int temp = 0; // 用作两两交换 int times = 0; // 作为记录每轮的中的比较后两数的交换次数,如果该轮比较后两数的交换次数为0,那么此时的数组就已经为升序排序了 for (int j = 0; j < arr.length - 1 - i; j ++) { System.out.println("第[" + (j + 1) + "]次比较中比较的两个数字为:" + arr[j] + "," + arr[j + 1]); if (arr[j] > arr[j + 1]) { temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; times ++; } } System.out.println("本轮排序结束后的数组为:" + Arrays.toString(arr)); if (times == 0) { return; } } } private static int[] randomArr(int length) { Random random = new Random(); System.out.print("请输入数组的长度:"); int[] arr = new int[length]; for (int i = 0; i < arr.length; i++) { arr[i] = random.nextInt(101) + 1; } return arr; } }
-
2、二分查找
-
概念
- 普通查找是从前往后依次查找,效率比较低;二分查找的前提是数据要有顺序,依次查找排除一半的数据,效率高
-
思路
-
- 1.计算中间索引 = (最小索引+最大索引) / 2
- 2.拿要找的数字和中间索引对应的数据比较
- 3.如果要找的数据大于中间索引的数据,小索引=中间索引+1
- 4.如果要找的数据小于中间索引的数据,大索引=中间索引-1
- 5.循环条件左边小于等于右边
-
流程图
-
demo
-
import java.util.Arrays; import java.util.Random; import java.util.Scanner; public class BinarySearch { /* 二分查找原理: 顾名思义,就是在一个数组中查找一个特定的值 二分查找可以在每次查找后,减少一半的查找量 但是二分查找有个前提就是数组必须是先排序好的。 */ public static void main(String[] args) { // 随机生成(1-100)的指定长度的数组 Scanner scanner = new Scanner(System.in); System.out.print("请输入指定的数组长度:"); int[] arr = randomArr(scanner.nextInt()); System.out.println("源数组: arr = " + Arrays.toString(arr)); System.out.print("请输入要查找的元素:"); int key = scanner.nextInt(); int index = binarySearch(arr, key); if (index != -1) { System.out.println(key + "值在数组中的索引为:" + index); } else { System.out.println("数组中不存在" + key + "元素!"); } } private static int binarySearch(int[] arr, int key) { // 定义小索引min,和大索引max int min = 0; int max = arr.length - 1; // 循环查找 while (min <= max) { // 计算中间索引 // 中间索引 = (最小索引 + 最大索引) / 2 int middle = (min + max) / 2; // 拿要查找的元素和中间索引对应的元素比较 // 如果要查找的元素小于中间索引对应的元素,那么大索引等于中间索引-1 // 如果大于中间元素对应的索引,那么小索引等于中间索引+1 if (key < arr[middle]) { max = middle - 1; }else if (key > arr[middle]) { min = middle + 1; }else { return middle; } } return -1; } private static int[] randomArr(int length) { Random random = new Random(); System.out.print("请输入数组的长度:"); int[] arr = new int[length]; for (int i = 0; i < arr.length; i++) { arr[i] = random.nextInt(101) + 1; } Arrays.sort(arr); return arr; } }
-
3、图书管理系统
-
Book类
-
package Day07.ClassicCase.demo05图书管理系统.Personal; public class Book { private String name; private double price; public Book(String name, double price) { this.name = name; this.price = price; } public Book() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } @Override public String toString() { return "Book{" + "name='" + name + '\'' + ", price=" + price + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Book book = (Book) o; if (Double.compare(book.price, price) != 0) return false; return name != null ? name.equals(book.name) : book.name == null; } }
-
-
BookMenu类
-
package Day07.ClassicCase.demo05图书管理系统.Personal; import java.util.ArrayList; import java.util.HashMap; import java.util.Scanner; import java.util.function.BiConsumer; public class BookMenu { // 初始化书籍 // 即默认为此时是有部分数据的,用作演示 private static HashMap<String, ArrayList<Book>> map = new HashMap<>(); // 静态代码块(只在类加载的时候运行一次)---->用来初始化书籍 static { ArrayList<Book> famousBook = new ArrayList<>(); famousBook.add(new Book("西游记", 19.9)); famousBook.add(new Book("水浒传", 20.6)); famousBook.add(new Book("红楼梦", 23.8)); famousBook.add(new Book("三国演义", 26.7)); map.put("名著", famousBook); ArrayList<Book> itBook = new ArrayList<>(); itBook.add(new Book("Java从入门到入土", 99.99)); itBook.add(new Book("算法与数据结构", 99.99)); itBook.add(new Book("数据库原理与应用", 99.99)); itBook.add(new Book("Spring全家桶实战", 99.99)); map.put("IT书籍", itBook); } public static void main(String[] args) { while (true) { int choice = mainMenu(); switch (choice) { case 1: // 查看 showBook(); break; case 2: // 添加 addBook(); break; case 3: // 删除 deleteBook(); break; case 4: // 修改 editBook(); break; case 5: System.out.println("退出成功,感谢您的使用!"); System.exit(0); // return; default: System.out.println("抱歉,没有该选项,请重新输入!"); } } } private static void editBook() { // 1. 输入书籍类型 // 2. 根据书籍类型返回BookList // 3. 根据书名遍历找到当前书籍 // 4. 重新输入书籍名称和价格 // 5. 利用map的put方法更新书籍信息 } private static void deleteBook() { Scanner scanner = new Scanner(System.in); System.out.println("----------欢迎进入删除书籍界面!----------"); System.out.print("请输入要删除的书籍的类型:"); ArrayList<Book> books = map.get(scanner.nextLine()); if (books != null) { System.out.print("请输入要删除的书籍的名称:"); String bookName = scanner.nextLine(); // 根据书名进行书籍删除的话,有可能会删除多本书籍 // 因为在添加书籍的时候判断书籍重复是根据书名和价格一起来的 // System.out.print("请输入要删除的书籍的价格:"); // 因为有可能删除多本书籍,那么就需要考虑数组从后往前面删除 // 如果只删除一本书籍,那么数组删除,可以从前往后删除 // 所以可以看出,本案例设计明显失败!应该增加一个唯一的值,如书的ISBN // 因为我们日常逛商城可以发现,书名一样,价格不一样的书籍比比皆是 // 仅仅只按照书名来删除或者修改书籍的话,那么显然是非常不合理的! int count = 0; for (int i = books.size() - 1; i >= 0; i --) { if (books.get(i).getName().equals(bookName)) { if (books.remove(books.get(i))) { System.out.println("删除\t" + bookName + "\t书籍成功!"); count ++; } } } if (count == 0) { System.out.println( "\t" + bookName + "\t书籍不存在,删除失败!"); } }else { System.out.println("当前没有此类型的书籍,删除失败!"); } } private static void addBook() { Scanner scanner = new Scanner(System.in); System.out.println("----------欢迎进入添加书籍界面!----------"); System.out.print("请输入您要添加的书籍的类型:"); String bookType = scanner.nextLine(); if (map.containsKey(bookType)) { // 通过类型找到当前系统中存储的Book 的arraylist集合 ArrayList<Book> books = map.get(bookType); System.out.print("请输入您要添加的书籍的书名:"); String bookName = scanner.nextLine(); System.out.print("请输入您要添加的书籍的价格:"); double bookPrice = scanner.nextDouble(); Book newBook = new Book(bookName, bookPrice); if (books.contains(newBook)) { // ArrayList的contains方法中的底层是依靠类的equals方法进行判断的,所以需要重写equals方法 System.out.println("当前已存在此书籍,添加失败!"); } else { books.add(newBook); map.put(bookType, books); System.out.println("添加\t" + bookName + "\t书籍成功!"); } } else { System.out.println("当前系统中并没有此书籍类型,是否要添加新类型?(y/n)"); char key = scanner.nextLine().charAt(0); if (key == 'y') { System.out.print("请输入您要添加的书籍的书名:"); String bookName = scanner.nextLine(); System.out.print("请输入您要添加的书籍的价格:"); double bookPrice = scanner.nextDouble(); ArrayList<Book> books = new ArrayList<>(); books.add(new Book(bookName, bookPrice)); map.put(bookType, books); System.out.println("添加\t" + bookName + "\t书籍成功!"); }else if (key == 'n') { return; }else { System.out.println("输入错误,添加书籍失败!"); } } } private static void showBook() { System.out.println("----------欢迎进入查看书籍界面!----------"); System.out.println("书籍类型\t\t书名\t\t\t\t\t\t\t\t价格"); map.forEach(new BiConsumer<String, ArrayList<Book>>() { @Override public void accept(String key, ArrayList<Book> values) { System.out.print(key + "\t\t\n"); for (Book book : values) { System.out.print(" \t\t" + book.getName() + "\t\t\t\t\t\t\t\t"); System.out.print(book.getPrice() + "\n"); } } }); } private static int mainMenu() { Scanner scanner = new Scanner(System.in); System.out.println("----------欢迎进入猛男图书馆后台管理系统----------"); System.out.println(" 1.查看书籍"); System.out.println(" 2.添加书籍"); System.out.println(" 3.删除书籍"); System.out.println(" 4.修改书籍"); System.out.println(" 5.退出"); System.out.println("-----------------------------------------------"); System.out.print("请输入您的选择:"); return scanner.nextInt(); } }
-
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?