简单记录 - 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的更多相关文章

  1. [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 ...

  2. 二分查找(Binary Search)

    二分查找(Binary Search): int BinarySearch(int *array, int N, int key) { ; int left, right, mid; left = ; ...

  3. Leetcode之二分法专题-704. 二分查找(Binary Search)

    Leetcode之二分法专题-704. 二分查找(Binary Search) 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 t ...

  4. 二分查找(Binary Search)的递归和非递归

    Binary Search 有时候我们也把它叫做二进制查找 是一种较为高效的再数组中查找目标元素的方法 我们可以通过递归和非递归两种方式来实现它 //非递归 public static int bin ...

  5. LeetCode 108. 将有序数组转换为二叉搜索树(Convert Sorted Array to Binary Search Tree) 14

    108. 将有序数组转换为二叉搜索树 108. Convert Sorted Array to Binary Search Tree 题目描述 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索 ...

  6. 二分查找(Binary Search)的基本实现

    关于二分查找法二分查找法主要是解决在"一堆数中找出指定的数"这类问题. 而想要应用二分查找法,这"一堆数"必须有一下特征: 1,存储在数组中2,有序排列 所以如 ...

  7. 二分查找(binary search)java实现及时间复杂度

    概述 在一个已排序的数组seq中,使用二分查找v,假如这个数组的范围是[low...high],我们要的v就在这个范围里.查找的方法是拿low到high的正中间的值,我们假设是m,来跟v相比,如果m& ...

  8. [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 ...

  9. [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 ...

随机推荐

  1. JavaScript中遍历的几种方法

    1.while循环 while后面跟循环条件和执行语句,只要满足条件,就会一直执行里面的执行 var i = 0 while(){ console.log(i) i++ } 2.do...while循 ...

  2. Java-Word转PDF

    1. 下载jar包或者引入pom.xml 下载:https://www.e-iceblue.cn/Downloads/Free-Spire-Doc-JAVA.html 引入pom.xml:https: ...

  3. jmeter跨线程使用token

    项目的接口测试,今早所有接口都不通了,查看原因是登录接口地址变了..... 原来的方式是每个线程中都写了登陆接口来获取token,但是因为登陆接口地址改变的原因,要改好多个登陆接口,所以就想把toke ...

  4. 【JAVA基础】静态方法

    /* * 与Python的静态单例比较: * 一样是需要加上static方法才可以直接调用类里面的私有方法 * * Python的类方法上 加上装饰器@staticmethod就可以不用实例化类而直接 ...

  5. PHP基础再练习

    一.变量 字母 char , string 类型 数字 int,float类型 数组: 需要注意的是 1.变量名 区分大小写 2.数字不能当变量名开头 echo "var_dump就相当于 ...

  6. PHPCMS V9.6.3的后台漏洞分析

    PHPCMS V9.6.3后台的漏洞分析 1.利用文件包含创建任意文件getshell 漏洞文件:\phpcmsv9\phpcms\modules\block\block_admin.php 漏洞产生 ...

  7. kvm环境部署及常用指令

    Linux下通过kvm创建虚拟机,通过vnc连接,做好配置后,通过ssh登录,并开启iptables Kvm虚拟化搭建教程参考链接:https://jingyan.baidu.com/article/ ...

  8. 无法启动IIS Express Web服务器

    解决 打开项目文文件夹以.csproj结尾的文件),找到WebProjectProperties节点然后,将图中框选的三项节点内容全部清空 删除.vs 重新启动即可

  9. C++STL教程

    1 什么是STL? STL(Standard Template Library),即标准模板库,是一个具有工业强度的,高效的C++程序库.它被容纳于C++标准程序库(C++ Standard Libr ...

  10. oracle 19c dataguard silent install (oracle 19c dataguard 静默安装)

    环境说明 1.关闭透明大页 RHEL  6: # cat /sys/kernel/mm/redhat_transparent_hugepage/enabled [oracle@rhel 6 ~]$ c ...