java 二分查找 排序_排序集合和二分查找

29d249bfa733789c5214841f1065ed46.png排序集合和二分查找

1.有序集合

二分查找(也称折半查找)是非常重要和常见的查找算法,在平衡树和排序集合中应用较多。使用二分查找是有前提条件的,首先要保证集合时一个排序集合,只有在排序集合中才能使用二分查找。

在各种类型的数据中,一些数据天生就是有顺序的。比如数字,它天生就拥有自然排序的属性。还有一些数据类型,比如字符串,它也有约定俗成的排序规则。在Java语言中,判断一个类型的数据是否具有可排序的属性,通常看它本身是否实现了Comparable接口(比较器接口)。如果自定义的数据类型中实现了Comparable接口,它也是具有自然排序的属性。

Comparable接口是一个泛型接口,实现该接口需要实现"int compareTo(T o)"抽象方法,它的重写规则是:如果当前对象的值比o小,该方法返回一个负整数,否则返回一个正整数,如果两个值相等返回0。

在一些工具类容器中,为了避免出现泛型接口劫持的情况,允许向容器内添加非Comparable实现的类型,但必须额外提供一个外比较器Comparator对象,外比较器中的方法"int compare(T o1, T o2)"中定义了o1和o2的比较规则。这两种做法都可以保证自定义类型拥有排序属性。

2.二分查找

二分查找的思想非常简单,在一个已排序序列的一半处开始进行查找,根据比较的大小情况再决定向左还是向右继续进行查找。在使用二分查找算法时,通常需要定义三个比较索引,用于查找过程中对比较范围的约束:

1.left索引,在序列的最小元素处。

2.right索引,在序列的最大元素处。

3.middle索引,在序列的中间位置。

查找的目标值target总是与middle进行比较,当target大于middle时,left索引移动到middle+1处,随后middle索引移动到(left+right)/2处。

如果target小于middle时,right索引移动到middle-1处,随后随后middle索引移动到(left+right)/2处。直到left的索引大于right时,查找结束,如果查找结束时,依然没有找到有序集合中的target值,说明target值不在集合中(如下图所示)。

46e64ab84643a509a9a5a5b51ab92ef9.png二分查找算法

当我们要在Java中要设计一个排序集合时,就可以使用到二分查找的算法。我们无需从头设计一个全新的线性集合,可以在ArrayList的基础上进行改造,将其改造成排序集合,并增加二分查找方法。由于ArrayList本身不是排序集合,我们需要覆盖它的add方法,让进入容器的数据保持有序性(示例代码如下)。

4b80f5ed82e4edd1ec94575feea22b81.png

ddbcbfa1bcbd6c46a0f6f3e2e8b8d350.png

ecc03817284fabf6a4d9eee3e15e7f7f.png

改造完的SortList是变成了一个自然排序集合。我们可以随机生成一些数据,测试一下改造的SortList是否能够自动对元素进行排序,以及新添加的二分查找方法能否找到目标数据。

5643036febd0f7c07dea215d034dbd59.png

运行结果:

5920516bec21e267e609fedde01fa56a.png

通过上述示例的运行结果,可以验证我们改造的排序集合是有效的(可自行增加功能测试用例,验证代码的健壮性)。同时,我们也可以自定义一些类,来查看我们改造的SortList是否有效。在下面示例中,我们创建了学生成绩类TestScores,该类定义比较规则。在测试中,将多个学生成绩放入SortList中,看是否可以达到自动排序的效果。

762a00e5ce972f2bd44076c8592b46b6.png

dc35619bc97fb2b2b482b3498ef6ce95.png

运行结果:

40ac9de0dd61cd436142f7ded3054707.png

通过运行结果来看,达到了我们的预期效果。并且可以利用findInsertIndex方法实现一些统计效果。

虽然在Java中存在类似的排序集合(TreeMap、TreeSet等),但是对于二分查找这样的基础算法,我们还是需要掌握的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 下面是一个Java二分查找排序代码实现: ```java public class BinarySearch { public static int binarySearch(int[] arr, int key) { int low = 0; int high = arr.length - 1; while (low <= high) { int mid = (low + high) / 2; if (arr[mid] == key) { return mid; } else if (arr[mid] < key) { low = mid + 1; } else { high = mid - 1; } } return -1; } public static void main(String[] args) { int[] arr = {2, 5, 7, 8, 10, 12}; int key = 8; int index = binarySearch(arr, key); if (index == -1) { System.out.println("元素未找到!"); } else { System.out.println("元素在数组中的位置为:" + index); } } } ``` 这里 `binarySearch` 方法实现了二分查找算法,它接受一个已经排好序的数组 `arr` 和要查找的关键字 `key` 作为参数。函数返回关键字在数组中的索引位置,如果未找到则返回 -1。 在 `main` 函数中,我们定义了一个数组 `arr` 和一个要查找的关键字 `key`,然后调用 `binarySearch` 方法来查找关键字在数组中的位置。如果找到了,就输出它在数组中的位置,否则输出 "元素未找到!"。 ### 回答2: 二分查找(Binary Search)也叫折半查找,是一种高效的查找算法。它的前提是待查找集合必须是有序的。下面是用Java写一个二分查找排序的代码示例: ```java public class BinarySearch { // 二分查找算法 public static int binarySearch(int[] array, int target) { int low = 0; int high = array.length - 1; while (low <= high) { int mid = (low + high) / 2; if (array[mid] == target) { return mid; // 找到目标元素,返回索引 } else if (array[mid] < target) { low = mid + 1; // 目标元素在右半部,更新low } else { high = mid - 1; // 目标元素在左半部,更新high } } return -1; // 未找到目标元素,返回-1 } public static void main(String[] args) { int[] array = { 1, 3, 5, 7, 9, 11 }; // 有序数组 int target = 7; // 目标元素 int index = binarySearch(array, target); if (index != -1) { System.out.println("目标元素" + target + "在数组中的索引为" + index); } else { System.out.println("目标元素" + target + "未在数组中找到"); } } } ``` 以上代码定义了一个名为`BinarySearch`的类,其中包含了一个静态方法`binarySearch`来实现二分查找算法。在`main`方法中,创建了一个有序数组`array`,并指定要查找的目标元素为7。通过调用`binarySearch`方法,返回目标元素在数组中的索引。最后根据返回的索引结果输出查找结果。 以上就是一个用Java实现二分查找算法的例子,通过该算法可以高效地查找有序数组中的元素。 ### 回答3: 二分查找(Binary Search)是一种查找算法,思路是将有序数组成两部,通过每次查找中间元素与目标值比较的方式来不断缩小查找范围,最终找到目标值或确定其不存在。 以下是用Java编写的二分查找排序代码: ``` public class BinarySearch { public static int binarySearch(int[] arr, int target) { int left = 0; int right = arr.length - 1; while (left <= right) { int mid = (left + right) / 2; if (arr[mid] == target) { return mid; } else if (arr[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return -1; } public static void main(String[] args) { int[] arr = {1, 2, 3, 4, 5, 6}; int target = 4; int index = binarySearch(arr, target); if (index != -1) { System.out.println("目标值 " + target + " 的索引为 " + index); } else { System.out.println("目标值 " + target + " 不存在于数组中"); } } } ``` 在上述代码中,binarySearch方法使用了迭代的方式来实现二分查找。初始时,left指向数组的第一个元素,right指向数组的最后一个元素。通过计算中间元素的索引mid,将查找范围不断缩小。如果中间元素等于目标值,则返回该元素的索引;如果中间元素小于目标值,则在右侧继续查找;如果中间元素大于目标值,则在左侧继续查找。重复这个过程直到找到目标值或确定其不存在。 在主方法中,创建了一个有序数组arr和目标值target,并调用binarySearch方法来查找目标值在数组中的索引。如果返回的索引不为-1,则表示目标值存在于数组中,打印输出目标值和其对应的索引;否则,表示目标值不存在于数组中,打印输出该信息。 以上就是用Java实现二分查找排序的代码。该算法的时间复杂度为O(log n),其中n为数组的长度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值