Java学习第41天:顺序查找与折半查找

1、顺序查找

又称作线性查找,主要用于在线性表中进行查找。适用于对一般无序线性表的查找。基本思想:从线性表的一端开始查找,逐个检查关键字是否满足给定的条件。

2、折半查找

用于在有序的线性表中进行查找。基本思想:首先将给定的key值与线性表中中间位置的元素进行比较,若相等则查找成功,若不相等,则在线性表的中间元素之外的前半部分或后半部分进行查找。如此重复。

假设查找的数组区间为 [min,max],min 代表起始索引,max 代表结束索引,T 代表需要查找的值。

第一步:确定该区间的中间位置 K;
第二步:将查找的值 T 与 array[k] 比较。若相等,查找成功返回此位置;否则确定新的查找区域,继续折半查找;
第三步:若 array[k]>T,由数组的有序性可知 array[k,k+1,……,max] 中的每个值都大于 T,故新的区间为 array[min,……,K-1],若 array[k]<T,同理可得新的查找区间为 array[k+1,……,max]。
代码如下:

 package day41;

public class DataArray {
/**
     * @Description: 一个内部类
     * 在书上通常是用的int类型,这里根据闵老师的文章设计的键值类型数据
     */
    class DataNode {
        //键值
        int key;

        //数据
        String content;

        public DataNode(int key, String content) {
            this.key = key;
            this.content = content;
        }

        @Override
        public String toString() {
            return "(" + key + "," + content + ")";
        }
    }

    //数组
    DataNode[] data;

    //数据长度
    int length;

    /**
     * @Description: 构造函数
     * 形参数组的数量需要相一致
     * @Param: [paraKeyArray, paraContentArray]
     * @return:
     */
    public DataArray(int[] paraKeyArray, String[] paraContentArray) {
        length = paraKeyArray.length;
        data = new DataNode[length];
        for (int i = 0; i < length; i++) {
            data[i] = new DataNode(paraKeyArray[i], paraContentArray[i]);
        }
    }

    @Override
    public String toString() {
        String resString = "I am a data array with " + length + " items.\r\n";
        for (int i = 0; i < length; i++) {
            resString += data[i] + " ";
        }
        return resString;
    }

    /**
     * @Description: 顺序查找
     * 这里是设置第一个空间为哨兵,当到达哨兵的位置即表明未找到元素,查找方式是从后往前
     * @Param: [paraKey]
     * @return: java.lang.String
     */
    public String sequentialSearch(int paraKey) {
        data[0].key = paraKey;

        int i;

        for (i = length - 1; data[i].key != paraKey; i--)
            ;

        return data[i].content;
    }

    /**
     * @Description: 顺序查找测试
     * @Param: []
     * @return: void
     */
    public static void sequentialSearchTest() {
        int[] tempUnsortedKeys = {-1, 5, 3, 6, 10, 7, 1, 9};
        String[] tempContents = {"The target key is not exist.", "if", "then", "else", "switch", "case", "for", "while"};
        DataArray tempDataArray = new DataArray(tempUnsortedKeys, tempContents);

        System.out.println(tempDataArray);

        System.out.println("Search result of 10 is: " + tempDataArray.sequentialSearch(10));
        System.out.println("Search result of 5 is: " + tempDataArray.sequentialSearch(5));
        System.out.println("Search result of 4 is: " + tempDataArray.sequentialSearch(4));
    }

    /**
     * @Description: 二分查找
     * 前提条件是键值必须为有序
     * @Param: [paraKey]
     * @return: java.lang.String
     */
    public String binarySearch(int paraKey) {
        int left = 0;
        int right = length - 1;
        int mid = (left + right) / 2;

        while (left <= right) {
            mid = (left + right) / 2;
            if (data[mid].key == paraKey) {
                return data[mid].content;
            } else if (data[mid].key > paraKey) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }

        return "The target key is not exist.";
    }

    /**
     * @Description: 二分查找测试
     * @Param: []
     * @return: void
     */
    public static void binarySearchTest() {
        int[] tempSortedKeys = {1, 3, 5, 6, 7, 9, 10};
        String[] tempContents = {"if", "then", "else", "switch", "case", "for", "while"};
        DataArray tempDataArray = new DataArray(tempSortedKeys, tempContents);

        System.out.println(tempDataArray);

        System.out.println("Search result of 10 is: " + tempDataArray.binarySearch(10));
        System.out.println("Search result of 5 is: " + tempDataArray.binarySearch(5));
        System.out.println("Search result of 4 is: " + tempDataArray.binarySearch(4));
    }

    public static void main(String[] args) {
        System.out.println("\r\n-------sequentialSearchTest-------");
        sequentialSearchTest();

        System.out.println("\r\n-------binarySearchTest-------");
        binarySearchTest();
    }
}

运行结果:

-------sequentialSearchTest-------
I am a data array with 8 items.
(-1,The target key is not exist.) (5,if) (3,then) (6,else) (10,switch) (7,case) (1,for) (9,while) 
Search result of 10 is: switch
Search result of 5 is: if
Search result of 4 is: The target key is not exist.

-------binarySearchTest-------
I am a data array with 7 items.
(1,if) (3,then) (5,else) (6,switch) (7,case) (9,for) (10,while) 
Search result of 10 is: while
Search result of 5 is: else
Search result of 4 is: The target key is not exist.

注:

1.顺序查找使用岗哨可以节约一半的时间. 为此, 第 0 个位置不可以放有意义的数据, 即有效数据只有 length - 1 个.
2.顺序查找时间复杂度为 O ( n ) .
3.折半查找时间复杂度为 O ( log ⁡n ) .
4.书上为简化起见, 只关注键. 这里使用键值对来表示一条完整的数据. 实际应用中可以把 content 改成任何想要的数据类型.

5.在查找速度方面,顺序查找自然是不及折半查找,从另一方面来说,顺序查找对数据要求不高,无需数据按照某种方式排列,也无需指定存储格式。所以从应用范围来说,顺序查找算法自然会更好。
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值