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();
      }
      }
posted @   OnlyOnYourself-Lzw  阅读(113)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示