数据结构Java版的查找算法实现

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

/**
 * 查找的基本算法:
 *                                         - 顺下查找
 *            -基于线性表的查找(静态查找)- 折半查找
 *            -                            - 分块查找
 *            -
 * 比较式查找 -
 *            -                            - 二叉排序树(B树)
 *            -                            - 平衡二叉树
 *            -基于树的查找(动态查找)
 *            -                            - B- 树
 *            -                            - B+ 树
 * 计算式查找 -  -  - -  -  -              - Hash查找
 *
 *  2017/8/8.
 */
public class SearchMethod {
    public static void main(String[] agrs){
        int[] num = new int[]{7,9,10,8,2,1,3,4,6,5,20,25,56,0,13,14,15};
//        System.out.println(OrderSearch(num,2));
//        System.out.println(BinarSearch(num,2));
//        int index = BlockSearch(num,SplitBlock(num,3),0);
//        System.out.println(index);
          //构建二叉排序树
//        BinarySortTree b = new BinarySortTree();
//        b.val = 5;
//        b.left_child = new BinarySortTree();
//        b.right_child = new BinarySortTree();
//        b.left_child.val = 3;
//        b.right_child.val = 7;
//        b.left_child.left_child = new BinarySortTree();
//        b.left_child.right_child = new BinarySortTree();
//        b.left_child.left_child.val = 2;
//        b.left_child.right_child.val = 4;
//        b.right_child.left_child = new BinarySortTree();
//        b.right_child.right_child = new BinarySortTree();
//        b.right_child.left_child.val = 6;
//        b.right_child.right_child.val = 8;
//        SearchMethod search = new SearchMethod();
//        System.out.println(search.BinaryTreeSearch(b,9));


    }

    /** 1
     * 顺序查找:逐个比较,直到找到或者查找失败。
     * 时间复杂度可以表示O(h)=O(n)
     * 空间复杂度:S(n) = O(n)
     * @param num 查找的数组
     * @param n 查找的数
     * @return 返回下标
     */
    public static int OrderSearch(int[] num,int n){
        for (int i = 0; i < num.length - 1; i++) {
            if (num[i] == n){
                return i;
            }
        }
        return -1;

    }

    /** 2
     * 二分法查找:对于已经按照一定顺序排列好的列表,
     * 每次都用关键字和中间的元素对比,然后判断是在前部分还是后部分还是就是中间的元素,
     * 然后继续用关键字和中间的元素对比。
     * 时间复杂度可以表示O(h)=O(log2n)
     * @param num 查找的数组
     * @param n 查找的数
     * @return 返回下标
     */
    public static int BinarSearch(int[] num,int n){
        int low = 0;
        int high = num.length - 1;
        while (low <= high){
            int mid = (low+high)/2;
            int tem = num[mid];
            if (tem < n){
                low = mid + 1;
            }else if (tem > n){
                high = mid - 1;
            }else {
                return mid;
            }
        }
        return -1;
    }

    /**
     * 分块查找的分块:0<可分块<=查找数组元素和
     * 采用Hashmap保存区块的极值和起始下标
     * @param num 查找数组
     * @param n 分块个数
     * @return 返回分块起始下标和块的最大值
     */
    public static HashMap<Integer,Integer> SplitBlock(int[] num,int n){
        HashMap<Integer,Integer> block = new HashMap<>();
        int tem = num[0];
        for (int i = 0; i < num.length - 1; i++) {
            if (i % n == 0){ //起始分块
                if ((i+n) >= num.length-1){ //判断是否是最后一个区块 最后一个区块元素可能小于或大于前面区块元素
                    for (int j = i; j < num.length; j++) { //区块内查找极值
                        if (num[j] > tem){
                            tem = num[j];
                        }
                    }
                    //保存区块极值和起始下标
                    block.put(tem,i);
                }else {
                    for (int j = i; j < i+n; j++) { //区块内查找极值
                        if (num[j] > tem){
                            tem = num[j];
                        }
                    }
                    //保存区块极值和起始下标
                    block.put(tem,i);
                    //初始化区块比较值
                    tem = num[i+n-1];
                }
            }
        }
        return block;
    }

    /**
     * 分块查找:可查找任意无排序的数组
     * step1 先选取各块中的最大关键字构成一个索引表
     * step2 查找分两个部分:先对索引表进行二分查找或 顺序查找,然后在确定的块中顺序查找。
     * ASLbs=(n/s+s)/2  +1,(其中s是每块的元素个数,n为表长)
     * 时间复杂度为O(n)~O(log2n)
     * @param num
     * @param index
     * @param n
     * @return
     */
    public static int BlockSearch(int[] num,HashMap<Integer,Integer> index,int n){
        //获取索引极值进行排序
        Iterator<Integer> ite = index.keySet().iterator();
        int[] index1 = new int[index.size()];
        int i = 0;
        while (ite.hasNext()){
            index1[i++] = ite.next();
        }
        //索引极值从小到大排序
        Arrays.sort(index1);
        //查找元素所在区块
        for (int j = 0; j < index1.length; j++) {
            if (n <= index1[j]){ //小于索引值说明在此区块内进行查找
                int start = index.get(index1[j]);
                int end = 0;
                if (j != index1.length -1){
                    end = index.get(index1[j+1]);
                }else {
                    end = num.length;
                }
                //查找区块元素位置
                for (int k = start; k < end; k++) {
                        if (n == num[k]){
                            return k;
                        }
                }
            }
        }
        return -1;
    }

    /**
     * 二叉排序树/B树查找
     * 时间复杂度:O(logn)
     * @param b 二叉排序树
     * @param n 查找值
     * @return 返回结果
     */
   public int BinaryTreeSearch(BinarySortTree b,int n){
       if (b != null){
           if (b.val == n){
               return 1;
           }else if (b.val > n){
               return BinaryTreeSearch(b.left_child,n);
           }else if (b.val < n){
               return BinaryTreeSearch(b.right_child,n);
           }
       }
       return -1;
   }
   //平衡二叉树:且具有以下性质:它是一 棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
    //最小二叉平衡树的节点的公式如下 F(n)=F(n-1)+F(n-2)+1
    //查找与二叉排序树一样
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值