【二分搜索树】1、二分查找法的实现 - Binary Search
简单记录 - bobo老师的玩转算法系列–玩转算法 - 二分搜索树
二叉搜索树 Binary Search Tree
查找问题 Searching Problem
查找问题是计算机中非常重要的基础问题
二分查找法 Binary Search
v
<v v >v
对于有序数列,才能使用二分查找法 (排序的作用)
二分查找法的思想在1946年提出。
第一个没有bug的二分查找法在1962年才出现。
操作:实现二分查找法
非递归的二分查找算法 BinarySearch.java
package algo;
// 非递归的二分查找算法
public class BinarySearch {
// 我们的算法类不允许产生任何实例
private BinarySearch() {}
// 二分查找法,在有序数组arr中,查找target
// 如果找到target,返回相应的索引index
// 如果没有找到target,返回-1
public static int find(Comparable[] arr, Comparable target) {
// 在arr[l...r]之中查找target
int l = 0, r = arr.length-1;
while( l <= r ){
//int mid = (l + r)/2;
// 防止极端情况下的整形溢出,使用下面的逻辑求出mid
int mid = l + (r-l)/2;
if( arr[mid].compareTo(target) == 0 )
return mid;
if( arr[mid].compareTo(target) > 0 )
r = mid - 1;
else
l = mid + 1;
}
return -1;
}
// 测试非递归的二分查找算法
public static void main(String[] args) {
int N = 1000000;
Integer[] arr = new Integer[N];
for(int i = 0 ; i < N ; i ++)
arr[i] = new Integer(i);
// 对于我们的待查找数组[0...N)
// 对[0...N)区间的数值使用二分查找,最终结果应该就是数字本身
// 对[N...2*N)区间的数值使用二分查找,因为这些数字不在arr中,结果为-1
for(int i = 0 ; i < 2*N ; i ++) {
int v = BinarySearch.find(arr, new Integer(i));
if (i < N)
assert v == i;
else
assert v == -1;
}
return;
}
}
使用递归地方式实现二分查找法
递归实现通常思维起来更容易。
递归在性能上会略差。
练习:实现二分查找法的递归实现
package algo;
// 递归的二分查找算法
public class BinarySearch2 {
// 我们的算法类不允许产生任何实例
private BinarySearch2() {}
private static int find(Comparable[] arr, int l, int r, Comparable target){
if( l > r )
return -1;
//int mid = (l+r)/2;
// 防止极端情况下的整形溢出,使用下面的逻辑求出mid
int mid = l + (r-l)/2;
if( arr[mid].compareTo(target) == 0 )
return mid;
else if( arr[mid].compareTo(target) > 0 )
return find(arr, l, mid-1, target);
else
return find(arr, mid+1, r, target);
}
// 二分查找法,在有序数组arr中,查找target
// 如果找到target,返回相应的索引index
// 如果没有找到target,返回-1
public static int find(Comparable[] arr, Comparable target) {
return find(arr, 0, arr.length-1, target);
}
// 测试递归的二分查找算法
public static void main(String[] args) {
int N = 1000000;
Integer[] arr = new Integer[N];
for(int i = 0 ; i < N ; i ++)
arr[i] = new Integer(i);
// 对于我们的待查找数组[0...N)
// 对[0...N)区间的数值使用二分查找,最终结果应该就是数字本身
// 对[N...2*N)区间的数值使用二分查找,因为这些数字不在arr中,结果为-1
for(int i = 0 ; i < 2*N ; i ++) {
int v = BinarySearch2.find(arr, new Integer(i));
if (i < N)
assert v == i;
else
assert v == -1;
}
return;
}
}
比较
Main
package algo;
import algo.BinarySearch;
import algo.BinarySearch2;
// 比较非递归和递归写法的二分查找的效率
// 非递归算法在性能上有微弱优势
public class Main {
private Main(){}
public static void main(String[] args) {
int N = 1000000;
Integer[] arr = new Integer[N];
for(int i = 0 ; i < N ; i ++)
arr[i] = new Integer(i);
// 测试非递归二分查找法
long startTime = System.currentTimeMillis();
// 对于我们的待查找数组[0...N)
// 对[0...N)区间的数值使用二分查找,最终结果应该就是数字本身
// 对[N...2*N)区间的数值使用二分查找,因为这些数字不在arr中,结果为-1
for(int i = 0 ; i < 2*N ; i ++) {
int v = BinarySearch.find(arr, new Integer(i));
if (i < N)
assert v == i;
else
assert v == -1;
}
long endTime = System.currentTimeMillis();
System.out.println("Binary Search (Without Recursion): " + (endTime - startTime) + "ms");
// 测试递归的二分查找法
startTime = System.currentTimeMillis();
// 对于我们的待查找数组[0...N)
// 对[0...N)区间的数值使用二分查找,最终结果应该就是数字本身
// 对[N...2*N)区间的数值使用二分查找,因为这些数字不在arr中,结果为-1
for(int i = 0 ; i < 2*N ; i ++) {
int v = BinarySearch2.find(arr, new Integer(i));
if (i < N)
assert v == i;
else
assert v == -1;
}
endTime = System.currentTimeMillis();
System.out.println("Binary Search (With Recursion): " + (endTime - startTime) + "ms");
}
}
D:\Environments\jdk-11.0.2\bin\java.exe -javaagent:D:\Java\ideaIU-2019.2.win\lib\idea_rt.jar=9455:D:\Java\ideaIU-2019.2.win\bin -Dfile.encoding=UTF-8 -classpath D:\IdeaProjects\imooc\Learning-Algorithms\05-Binary-Search-Tree\out\production\01-Binary-Search algo.Main
Binary Search (Without Recursion): 337ms
Binary Search (With Recursion): 514ms
Process finished with exit code 0
比较非递归和递归写法的二分查找的效率
非递归算法在性能上有微弱优势
【二分搜索树】1、二分查找法的实现 - Binary Search的更多相关文章
- [Swift]LeetCode272. 最近的二分搜索树的值 II $ Closest Binary Search Tree Value II
Given a non-empty binary search tree and a target value, find k values in the BST that are closest t ...
- 二分查找(Binary Search)
二分查找(Binary Search): int BinarySearch(int *array, int N, int key) { ; int left, right, mid; left = ; ...
- Leetcode之二分法专题-704. 二分查找(Binary Search)
Leetcode之二分法专题-704. 二分查找(Binary Search) 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target ,写一个函数搜索 nums 中的 t ...
- 二分查找(Binary Search)的递归和非递归
Binary Search 有时候我们也把它叫做二进制查找 是一种较为高效的再数组中查找目标元素的方法 我们可以通过递归和非递归两种方式来实现它 //非递归 public static int bin ...
- LeetCode 108. 将有序数组转换为二叉搜索树(Convert Sorted Array to Binary Search Tree) 14
108. 将有序数组转换为二叉搜索树 108. Convert Sorted Array to Binary Search Tree 题目描述 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索 ...
- 二分查找(Binary Search)的基本实现
关于二分查找法二分查找法主要是解决在"一堆数中找出指定的数"这类问题. 而想要应用二分查找法,这"一堆数"必须有一下特征: 1,存储在数组中2,有序排列 所以如 ...
- 二分查找(binary search)java实现及时间复杂度
概述 在一个已排序的数组seq中,使用二分查找v,假如这个数组的范围是[low...high],我们要的v就在这个范围里.查找的方法是拿low到high的正中间的值,我们假设是m,来跟v相比,如果m& ...
- [Swift]LeetCode108. 将有序数组转换为二叉搜索树 | Convert Sorted Array to Binary Search Tree
Given an array where elements are sorted in ascending order, convert it to a height balanced BST. Fo ...
- [Swift]LeetCode109. 有序链表转换二叉搜索树 | Convert Sorted List to Binary Search Tree
Given a singly linked list where elements are sorted in ascending order, convert it to a height bala ...
随机推荐
- js实现弹幕
弹幕是一个很常见的功能,下面是本人封装的一个小小的实现方案,存在不足之处可以提出来或自由改进. 直接上代码:复制可运行 <!DOCTYPE html> <html> <h ...
- Java中四舍五入
1.Math中四舍五入的方法 Math.ceil(double a)向上舍入,将数值向上舍入为最为接近的整数,返回值是double类型 Math.floor(double a)向下舍入,将数值向下舍入 ...
- 【震惊】padding-top的百分比值参考对象竟是父级元素的宽度
引言 书写页面样式与布局是前端工程师Coding 中必不可少的一项工作,在定义页面元素的样式时,padding 属性也是经常被使用到的. padding 属性用于设置元素的内边距,其值可以是lengt ...
- vue第十七单元(电商项目逻辑处理,电商划分)
第十七单元(电商项目逻辑处理,电商划分) #课程目标 1.什么是电商项目 2.什么是B2B,B2C,C2C模式,常见的电商项目 3.移动端电商项目常见的逻辑处理 4.[知识扩展]传统系统架构及分布式系 ...
- Python编程基础:循环结构
一.为什么要用循环 现在有一个任务,要求你输出一百遍"好好学习,天天向上!",想一想,你会怎么做? (一)老老实实的笨方法 print("第1遍写:好好学习,天天向上!& ...
- Autofac的基本使用---目录
目录 Autofac的基本使用---1.前言 Autofac的基本使用---2.普通类型 Autofac的基本使用---3.泛型类型 Autofac的基本使用---4.使用Config配置 Autof ...
- python序列(十)字典
字典是无序可变序列. 定义字典是,每个元素的键和值用冒号分隔,元素之间用逗号分隔,所有的元素放在一对大括号"{ }"中. 字典中的键可以为任意不可变数据,比如.整数.实数.复数.字 ...
- 浅谈IAT加密原理及过程
上一次做完代码段加密后,又接触到了新的加密方式:IAT加密 IAT加密是通过隐藏程序的导入表信息,以达到增加分析程序的难度.因为没有导入表,就无法单纯的从静态状态下分析调用了什么函数,动态调试时,也无 ...
- 栈面板类StackPane?
创建栈面板,将在其上放置两个按钮,并用样式属性设置按钮和栈面板的外观样式. package yuan; //栈面板的应用 import javafx.application.Application; ...
- hashmap简单实现
p.p1 { margin: 0; font: 11px Monaco } p.p2 { margin: 0; font: 11px Monaco; min-height: 15px } p.p3 { ...