二分查找、分块查找、冒泡排序、选择排序、插入排序、快速排序 ...

打印 上一主题 下一主题

主题 1762|帖子 1762|积分 5286

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
二分查找/折半查找



  • 前提条件:数组中的数据必须是有序的
  • 核心逻辑:每次排除一半的查找范围
  • 优点:进步查找效率
  • 代码
    1. public static int binarySearch(int[] arr, int num) {
    2.     int start = 0;
    3.     int end = arr.length - 1;
    4.     while (start <= end) {
    5.         int mid = (start + end) / 2;
    6.         if (num == arr[mid]) {
    7.             // 找到
    8.             return mid;
    9.         } else if (num > arr[mid]) {
    10.             // num在mid索引的右边
    11.             start = mid + 1;
    12.         } else {
    13.             // num在mid索引的左边
    14.             end = mid - 1;
    15.         }
    16.     }
    17.     return -1;
    18. }
    复制代码
分块查找



  • 分块的原则

    • 前一块中的最大数据,小于后一块中全部的数据(块内无序,块间有序)
    • 块数数量一样寻常等于数字个数开根号。好比:16个数字一样寻常分为4块左右
    • 核心思路:先确定要查找的元素在哪一块,然后在块内挨个查找

  • 代码
    1. package com.gen.test;
    2. public class BlockSearchDemo {
    3.     public static void main(String[] args) {
    4.         int[] arr = {16, 5, 9, 12, 21, 18,
    5.                 32, 23, 37, 26, 45, 34,
    6.                 50, 48, 61, 52, 73, 66};
    7.         // 创建3个对象
    8.         Block block1 = new Block(21, 0, 5);
    9.         Block block2 = new Block(45, 6, 11);
    10.         Block block3 = new Block(73, 12, 17);
    11.         // 定义数组管理3个块的对象(索引表)
    12.         Block[] blockArr = {block1, block2, block3};
    13.         // 获取索引
    14.         int index = getIndex(blockArr, arr, 66);
    15.         System.out.println(index);
    16.     }
    17.     /**
    18.      * 获取索引
    19.      *
    20.      * @param blockArr 索引表
    21.      * @param arr      数组
    22.      * @param num      要查找的数字
    23.      * @return 返回数字在arr中的索引,-1表示不存在
    24.      */
    25.     private static int getIndex(Block[] blockArr, int[] arr, int num) {
    26.         // 1.先确定在哪一个块中
    27.         int indexBlock = findIndexBlock(blockArr, num);
    28.         // num比所有块的最大值要大,不存在数组中
    29.         if (indexBlock == -1) {
    30.             return -1;
    31.         }
    32.         // 2.在块中查找num
    33.         int startIndex = blockArr[indexBlock].getStartIndex();
    34.         int endIndex = blockArr[indexBlock].getEndIndex();
    35.         for (int i = startIndex; i <= endIndex; i++) {
    36.             if (num == arr[i]) {
    37.                 return i;
    38.             }
    39.         }
    40.         return -1;
    41.     }
    42.     /**
    43.      * 查找num在哪一个块中
    44.      *
    45.      * @param blockArr
    46.      * @param num
    47.      * @return 返回块索引,-1表示不存在
    48.      */
    49.     private static int findIndexBlock(Block[] blockArr, int num) {
    50.         for (int i = 0; i < blockArr.length; i++) {
    51.             if (num <= blockArr[i].getMax()) {
    52.                 return i;
    53.             }
    54.         }
    55.         return -1;
    56.     }
    57. }
    58. class Block {
    59.     // 最大值
    60.     private int max;
    61.     // 起始索引
    62.     private int startIndex;
    63.     // 结束索引
    64.     private int endIndex;
    65.     public Block() {
    66.     }
    67.     public Block(int max, int startIndex, int endIndex) {
    68.         this.max = max;
    69.         this.startIndex = startIndex;
    70.         this.endIndex = endIndex;
    71.     }
    72.     public int getMax() {
    73.         return max;
    74.     }
    75.     public void setMax(int max) {
    76.         this.max = max;
    77.     }
    78.     public int getStartIndex() {
    79.         return startIndex;
    80.     }
    81.     public void setStartIndex(int startIndex) {
    82.         this.startIndex = startIndex;
    83.     }
    84.     public int getEndIndex() {
    85.         return endIndex;
    86.     }
    87.     public void setEndIndex(int endIndex) {
    88.         this.endIndex = endIndex;
    89.     }
    90. }
    复制代码
冒泡排序



  • 排序逻辑

    • 相邻的元素两两比较,大的放右边,小的放左边
    • 第一轮循环结束,最大值已经找到,在数组的最右边
    • 第二轮循环只要在剩余的元素找最大值就可以了
    • 第二轮循环结束,次大值已经确定,第三轮循环继承在剩余数据中循环

  • 核心

    • 相邻的元素两两比较,大的放右边,小的放左边
    • 第一轮比较完毕之后,最大值就已经确定,第二轮可以少循环一次,反面以此类推
    • 如果数组中有n个数据,总共我们只要实行n-1轮的代码即可

  • 代码
    1. public static void bubbleSort(int[] arr) {
    2.     for (int i = 0; i < arr.length - 1; i++) {
    3.         for (int j = 0; j < arr.length - 1 - i; j++) {
    4.             if (arr[j] > arr[j + 1]) {
    5.                 // 左边数据比右边大,交换位置
    6.                 int temp = arr[j];
    7.                 arr[j] = arr[j + 1];
    8.                 arr[j + 1] = temp;
    9.             }
    10.         }
    11.     }
    12. }
    复制代码
选择排序



  • 从0索引开始,拿着每一个索引上的元素跟反面的元素依次比较,小的放前面,大的放反面,以此类推
  • 代码
    1. public static void selectSort(int[] arr) {
    2.     for (int i = 0; i < arr.length - 1; i++) {
    3.         for (int j = i + 1; j < arr.length; j++) {
    4.             if (arr[i] > arr[j]) {
    5.                 // 左边数据比右边大,交换位置
    6.                 int temp = arr[i];
    7.                 arr[i] = arr[j];
    8.                 arr[j] = temp;
    9.             }
    10.         }
    11.     }
    12. }
    复制代码
插入排序



  • 将0索引的元素到N索引的元素看作是有序的,把N+1索引的元素到末了一个当成是无序的
  • 遍历无序的数据,将遍历到的元素插入有序序列中适当的位置,如碰到雷同数据,插在反面
  • N的范围:0~最大索引
    1. package com.gen.test;
    2. public class InsertSortDemo {
    3.     public static void main(String[] args) {
    4.         int[] arr = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
    5.         // 1.找到无序索引起始位置
    6.         int startIndex = -1;
    7.         for (int i = 0; i < arr.length - 1; i++) {
    8.             if (arr[i] > arr[i + 1]) {
    9.                 startIndex = i + 1;
    10.                 break;
    11.             }
    12.         }
    13.         // 2.遍历无序元素,依次插入到有序元素中
    14.         for (int i = startIndex; i < arr.length; i++) {
    15.             // 记录当前要插入数据的索引
    16.             int j = i;
    17.             while (j > 0 && arr[j] < arr[j - 1]) {
    18.                 // 交换位置
    19.                 int temp = arr[j];
    20.                 arr[j] = arr[j - 1];
    21.                 arr[j - 1] = temp;
    22.                 j--;
    23.             }
    24.         }
    25.     }
    26. }
    复制代码
快速排序

第一轮:把0索引的数字作为基准数,确定基准数在数组中精确的位置。比基准数小的全部在左边,比基准数大的全部在右边
  1. /**
  2. * 快速排序
  3. *
  4. * @param arr 要排序的数组
  5. * @param i   开始索引
  6. * @param j   结束索引
  7. */
  8. public static void quickSort(int[] arr, int i, int j) {
  9.     // 递归出口
  10.     if (i >= j) {
  11.         return;
  12.     }
  13.     int start = i;
  14.     int end = j;
  15.     // 记录基准数
  16.     int baseNum = arr[i];
  17.     while (start != end) {
  18.         // 从后往前找,找到比基准数小的元素
  19.         while (true) {
  20.             if (start >= end || arr[end] < baseNum) {
  21.                 break;
  22.             }
  23.             end--;
  24.         }
  25.         // 从前往后找,找到比基准数大的元素
  26.         while (true) {
  27.             if (start >= end || arr[start] > baseNum) {
  28.                 break;
  29.             }
  30.             start++;
  31.         }
  32.         // 把start和end元素进行交换
  33.         int temp = arr[start];
  34.         arr[start] = arr[end];
  35.         arr[end] = temp;
  36.     }
  37.     // 基准数归位
  38.     arr[i] = arr[start];
  39.     arr[start] = baseNum;
  40.     // 递归排序左边的数
  41.     quickSort(arr, i, start - 1);
  42.     // 递归排序右边的数
  43.     quickSort(arr, start + 1, j);
  44. }
复制代码
排序总结



  • 冒泡排序

    • 相邻的元素两两比较,小的放前面,大的放反面

  • 选择排序

    • 从0索引开始,拿着每一个索引上的元素跟反面的元素依次比较,小的放前面,大的放反面,以此类推

  • 插入排序

    • 将数组分为有序和无序两组,遍历无序数据,将元素插入有序序列中即可

  • 快速排序

    • 将排序范围中的第一个数字作为基准数,再定义两个变量start、end
    • start从前去后找比基准数大的,end从后往前找比基准数小的
    • 找到之后交换start和end指向的元素,并循环这一过程,直到start和end处于同一个位置,该位置是基准数在数组中应存入的位置,再让基准数归位
    • 归位后的效果:基准数左边的,比基准数小,基准数右边的,比基准数大


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

吴旭华

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表