查找算法大汇总

本文详细介绍了几种常见的查找算法:顺序查找、二分查找(折半查找)、分块查找以及二叉搜索树查找。顺序查找简单直接但效率较低;二分查找适用于有序列表,效率较高;分块查找结合了顺序和二分的优点;二叉搜索树查找利用其特性快速定位元素。每种算法都提供了相应的Java代码实现,有助于理解和应用这些算法。
摘要由CSDN通过智能技术生成

顺序查找

    直接从头到尾遍历一遍就行,没啥好说的

   public int sequentialSearch(int[] nums,int target) {
        for (int i = 0; i < nums.length; i++) {
            if(nums[i]==target)return i;
        }
        return -1;
    }

二分查找(折半查找)

    二分查找也叫折半查找,是一种高效的查找方法。时间复杂度O(n),但是要注意的是只有顺序存储有序列表可以使用二分查找。

  1. 原理

    二分查找顾名思义是将列表分为两边。假设列表从小到大排列,首先判断中间位置是否等于查找元素,相等就返回当前位置。大于查找元素就对前半部分列表重复上述操作,小于查找元素就对后半部分列表重复上述操作。
    举个栗子:list:[0,1,2,3,4,5,6,7,8,9],target:5,也就是说我们要在列表中寻找值等于5的元素所在的位置。定义两个指针b=0,e=list.length-1一个指向列表开头,一个指向列表末尾。定义mid=(b+e)/2将数组分为两半

*表示b和e,&表示mid
 *       &         *	
[0,1,2,3,4,5,6,7,8,9]
list[mid](4)<target(5),因此target必定在mid的右边b=mid+1*   &   *	
[0,1,2,3,4,5,6,7,8,9]
list[mid](7)>target(5),因此target必定在mid的左边e=mid-1&
		   * * 	
[0,1,2,3,4,5,6,7,8,9]
list[mid](5)=target(5),返回mid
如果b>e,也就是头指针大于尾指针了那说明列表中没有target,返回-1;
  1. 代码实现
//常规写法
  public int binarySearch(int[] nums,int target) {
        int b=0,e=nums.length-1;
        while(b<=e){
            int mid=(b+e)/2;
            if(nums[mid]==target) return mid;
            if(nums[mid]<target){
                b=mid+1;
            }
            if(nums[mid]>target){
                e=mid-1;
            }
        }
        return -1;
    }
//递归写法
 public int binarySearch(int[] nums,int target,int b,int e) {
        if(b>e) return -1;
        int mid=(b+e)/2;
        if(nums[mid]<target)return binarySearch(nums,target,mid+1,e);
        if(nums[mid]>target)return binarySearch(nums,target,b,mid-1);
        else return mid;
    }

分块查找

    分块查找综合了顺序查找和二分查找。首先将元数据分为几个块(block)。块于块之间有序,块内的元素无序。然后先使用二分查找确定目标元素在哪个块中,之后再这个块中使用顺序查找最终确定元素的位置。

    public int blockSearch(int target) {
        int a = binarySearch(max, 0, max.size()-1, target);
        if(a==-1)return a;
        int end = a == index.size() - 1 ? nums.length-1 : index.get(a + 1);
        for (int i = index.get(a); i <=end; i++) {
            if (nums[i] == target) {
                return i;
            }
        }
        return -1;
    }

    public int binarySearch(List<Integer> max, int bg, int end, int target) {
        if(bg<0||end>=max.size()){
            return -1;
        }
        int mid = (bg + end) / 2;

        if(max.get(mid)==target)return mid;
        if (mid == max.size() - 1) {
            if (target < max.get(mid)&&target>max.get(mid-1)) {
                return mid;
            } 

        }

        if (mid == 0){
            if (target > max.get(mid)&&target<max.get(mid+1)) {
                return mid+1;
            }else if(target<max.get(mid))return mid;
         
        }
           
        if (max.get(mid) < target) {
            if (max.get(mid + 1) > target)
                return mid+1;
            else {
                return binarySearch(max, mid + 1, end, target);
            }
        }
        if (max.get(mid) > target) {
            if (max.get(mid - 1) < target)
                return mid;
            else {
                return binarySearch(max, bg, mid - 1, target);
            }
        }
        return -1;
    }

二叉搜索树查找

    二叉搜索树有一个特性

  1. 右子树的值大于等于根结点
  2. 左子树的值小于根结点
  3. 左右子树都是二叉搜索树

因此在查找二叉搜索树中查找元素时只要判断下于根节点的大小即可,大的往右子树找,小的往左子树找。
时间复杂度完全有序的情况下是O(n),平衡的情况下是O(logn)

package base.searchAlgorithm;

class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;

    TreeNode() {
    }

    TreeNode(int val) {
        this.val = val;
    }

    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}
public class SearchBST {
    public TreeNode searchBST(TreeNode root, int val) {
        while (root != null) {
            if (root.val == val)
                return root;
            else if (root.val > val)
                root = root.left;
            else if (root.val < val)
                root = root.right;
        }
        return root;
    }
}


TODO

  • 顺序查找
  • 二分查找
  • 分块查找
  • 二叉搜索树查找

源代码

源代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值