算法系列(二)查找算法--基本查找和二分查找

 算法系列(一)基本概念 一文中,简单介绍了算法基本概念,算法复杂度评估,常用算法证明方式。这篇文章介绍一下查找算法,主要是二分查找算法。

从n个元素中A0,A1....An-1中,找到要找到的元素x,最简单的方法是遍历n个元素,找到元素x则返回x的位置,这种算法的时间复杂度为O(n)。

如果这n个元素是有序的,我们不需要从头到尾遍历一遍就可以找到要查找的元素,可以使用二分法。二分查找的时间复杂度是O(lgn)

二分查找的前提是元素有序(一般是升序),基本思想是拿中间元素A[m]与要查找的元素x进行比较,如果相等,则已经找到,如果A[m]比x大,那么要找的元素一定在A[m]前边,如果A[m]比x小,那么要找的元素一定在A[m]后边。没进行一次查找,数组规模减半。反复将子数组规模减半,直到发现要查找的元素,或者当前子数组为空。

例如,在[1,2,3,4,5]中查找2

第一次找到的数字下标是(0+4)/2=2,找到的数字是3,3<2,要找的数字位置位于[0,2)之间

第二次找到的数字下标是(0+1)/2=0,找到的数字是1,1<2,要找的数字位于(0,1]之间

第三次找到的数字下标是(1+1)/2=1,找到数字2,返回找到的位置1.

如果这个时候找到的数字不是1,那么说明数组中没有要找的数字。

需要注意的点就是区间位置,既然A[m]不等于x,下一次肯定不是从m这个位置开始找的,而是以m+1作为下一个起始位置,或者m-1作为下一个开始位置

二分查找有两种实现方式,一种是递归实现,一种是非递归实现

直接上代码

[java]  view plain  copy
  1. package com.algorithm.tree;  
  2.   
  3. import java.util.Arrays;  
  4.   
  5. /** 
  6.  * 二分查找 
  7.  *  
  8.  * @author chao 
  9.  * 
  10.  */  
  11. public class BinarySearchTree {  
  12.     /** 
  13.      * 非递归二分查找 
  14.      *  
  15.      * @param num 
  16.      * @param number 
  17.      * @return 
  18.      */  
  19.     public static int binarySearch(int num[], int number) {  
  20.         if (num == null || num.length == 0) {  
  21.             return -1;  
  22.         }  
  23.         int start, end, mid;  
  24.         start = 0;  
  25.         end = num.length - 1;  
  26.         while (start <= end) {  
  27.             mid = (start + end) / 2;  
  28.             if (num[mid] == number)  
  29.                 return mid;  
  30.             else if (num[mid] > number) {  
  31.                 end = mid - 1;  
  32.             } else {  
  33.                 start = mid + 1;  
  34.             }  
  35.         }  
  36.         return -1;  
  37.     }  
  38.   
  39.     /** 
  40.      * 递归查找 
  41.      *  
  42.      * @param num 
  43.      * @param number 
  44.      * @return 
  45.      */  
  46.     public static int RecursivebinarySearch(int num[], int start, int end, int key) {  
  47.         int mid = (start + end) / 2;  
  48.         if (num == null || num.length == 0 || key < num[start] || key > num[end]) {  
  49.             return -1;  
  50.         } else if (num[mid] > key) {  
  51.             return RecursivebinarySearch(num, start, mid - 1, key);  
  52.         } else if (num[mid] < key) {  
  53.             return RecursivebinarySearch(num, mid + 1, end, key);  
  54.         } else {  
  55.             return mid;  
  56.         }  
  57.   
  58.     }  
  59.   
  60.     public static void main(String[] args) {  
  61.         int num[] = { 357910 };  
  62.         Arrays.sort(num);  
  63.         System.out.println(binarySearch(num, 7));  
  64.         System.out.println(binarySearch(num, 8));  
  65.         System.out.println(RecursivebinarySearch(num, 0, num.length - 17));  
  66.         System.out.println(RecursivebinarySearch(num, 0, num.length - 18));  
  67.     }  
  68. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值