查找所有满足条件的值:(1, 8, 10, 89, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1234) ,当一个有序数组中,有多个相同的数时,如何将所有的数值都查找到,比如这里的1000。
函数说明
- binarySearch函数:查找没有重复值的已排序数组。
- binarySearch2函数:查找有重复值的已排序数组。
代码实现
package chapter18.search
import scala.collection.mutable.ArrayBuffer
import util.control.Breaks._
object BinarySearch {
def main(args: Array[String]): Unit = {
// val arr = Array(1, 8, 10, 89, 1000, 1234)
// val index = binarySearch2(arr, 0, arr.length - 1, 1000)
// if (index != -1) {
// println(s"找到,下标为${index}")
// } else {
// println("未找到")
// }
val arr = Array(1, 8, 10, 89, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1234)
//将返回结果升序排序
val resArr = binarySearch2(arr, 0, arr.length - 1, 1000).sortBy((x: Int) => x)
if (resArr.length != 0) {
for (index <- resArr) {
println(s"找到的索引为:${index}")
}
} else {
println("未找到")
}
}
/**
*
* 升序情况下,二分查找思路:
* * 1.先找到中间值
* * 2.然后将中间值和查找值比较
* * 2.1相等,找出
* * 2.2中间值>查找值,向左进行递归查找
* * 2.3中间值<查找值,向右边进行递归查找
* * 如果存在这个值,就返回对应的下标,否则返回-1
*
* @param arr 待搜素数组
* @param l 左边索引
* @param r 右边索引
* @param findVal 目标值
* @return
*/
def binarySearch(arr: Array[Int], l: Int, r: Int, findVal: Int): Int = {
if (l > r) {
return -1
}
val midIndex = (l + r) / 2
val midVal = arr(midIndex)
if (midVal > findVal) {
binarySearch(arr, l, midIndex - 1, findVal)
} else if (midVal < findVal) {
binarySearch(arr, midIndex + 1, r, findVal)
} else {
return midIndex
}
}
/**
* 查找所有符合条件的值的下标
* 分析:
* 1.返回的结果是一个可变数组 ArrayBuffer
* 2.找到结果时,向左边扫描,向右边扫描。
* 3.找到结果后,就加入到ArrayBuffer
*
* @param arr
* @param l
* @param r
* @param findVal
* @return
*/
def binarySearch2(arr: Array[Int], l: Int, r: Int, findVal: Int): ArrayBuffer[Int] = {
if (l > r) {
return ArrayBuffer()
}
val midIndex = (l + r) / 2
val midVal = arr(midIndex)
if (midVal > findVal) {
binarySearch2(arr, l, midIndex - 1, findVal)
} else if (midVal < findVal) {
binarySearch2(arr, midIndex + 1, r, findVal)
} else {
//定义一个可变数组
var resArr = ArrayBuffer[Int]()
//向左边扫描
var temp = midIndex - 1
breakable {
while (true) {
if (temp < 0 || arr(temp) != findVal) {
break()
}
if (arr(temp) == findVal) {
resArr.append(temp)
}
temp -= 1
}
}
//将中间索引加入:
resArr.append(midIndex)
//向右边扫描
temp = midIndex + 1
breakable {
while (true) {
if (temp > arr.length - 1 || arr(temp) != findVal) {
break()
}
if (arr(temp) == findVal) {
resArr.append(temp)
}
temp += 1
}
}
return resArr
}
}
}