大话数据结构-查找

news2024/11/22 4:45:57

1 查找概论

  查找表(Search Table)是由同一类型的数据元素(或记录)构成的集合,如下所示:
在这里插入图片描述
  关键字(Key)是数据元素中某个数据项的值,又称为键值,用它可以标识一个数据元素,也可以标识一个记录的某个数据项(字段),我们称为关键码。
  若此关键字可以唯一地标识一个记录,则称此关键字为主关键字(Primary Key)。对于那些可以识别多个数据元素(或记录)的关键字,我们称为次关键字(Secondary Key)。
  查找(Searching)就是根据给定的某个值,在查找表中确定一个其关键字等于给定值的数据元素(或记录)。

  查找表按照操作方式来分有两大种:静态查找表和动态查找表。
  静态查找表(Static Search Table):只作查找操作的查找表。它的主要操作有:
  (1) 查找某个特定的数据元素是否在查找表中;
  (2) 检索某个特定的数据元素和各种属性;
  动态查找表(Dynamic Search Table):在查找过程中同时插入查找表中不存在的数据元素,或者从查找表中删除已经存在的某个数据元素。动态查找表的操作有两个:
  (1) 查找时插入数据元素;
  (2) 查找时删除数据元素;

  为了提高查找的效率,我们需要专门为查找操作设置数据结构,这种面向查找操作的数据结构称为查找结构。

2 顺序查找表

  顺序查找(Sequential Search)又叫线性查找,是最基本的查找技术,它的查找过程是:从表中第一个(或最后一个)记录开始,逐个进行记录的关键字和给定值比较,若某个记录的关键字和给定值相等,则查找成功,找到所查的记录;如果直到最后一个(或第一个)记录,其关键字和给定值比较都不等时,则表中没有所查的记录,查找不成功。

  代码实现较为简单:

/**
 * sequential search
 *
 * @author Korbin
 * @date 2023-04-19 11:01:06
 **/
public class SequentialSearch<T extends Comparable<T>> {

    /**
     * sequential search
     *
     * @param data search key in this array
     * @param key  to be searched key
     * @return the index of key in data
     * @author Korbin
     * @date 2023-04-19 11:23:13
     **/
    public int sequentialSearch(T[] data, T key) {
        int n = data.length;

        if (data[0].equals(key)) {
            return 0;
        }

        data[0] = key;

        int i = n - 1;
        while (!data[i].equals(key)) {
            i--;
        }
        return i;
    }

}

3 有序表查找

3.1 折半查找

  折半查找(Binary Search)技术,又称为二分查找,它的前提是线性表中的记录必须是关键码有序(通常从小到大有序),线性表必须采用顺序存储。

  折半查找的基本思想是:在有序表中,取中间记录作为比较对象,若给定值与中间记录的关键字相等,则查找成功;若给定值小于中间记录的关键字,则在中间记录的左半区继续查找;若给定值大于中间记录的关键字,则在中间记录的右半区继续查找。不断重复上述过程,直到查找成功,或所有查找区域无记录,查找失败为止。

  代码有多种实现方式,以下是示例:

/**
 * Binary Search
 *
 * @author Korbin
 * @date 2023-04-19 17:57:03
 **/
public class BinarySearch<T extends Comparable<T>> {

    /**
     * binary search
     * <p>
     * return index in data if searched, else return -1
     *
     * @param data array to search
     * @param key  key to search
     * @return index of key in data
     * @author Korbin
     * @date 2023-04-19 18:30:33
     **/
    public int binarySearch(T[] data, T key) {
        int length = data.length;

        int from = 0;
        int to = length - 1;

        // if key little than data[0] or key greater than data[length - 1], return -1, means search failed
        if (data[from].compareTo(key) > 0 || data[to].compareTo(key) < 0) {
            return -1;
        }

        int mid = ((to - from) + 1) / 2;

        while (from < to) {

            // if data[mid] equals key, then return mid
            if (data[mid].equals(key)) {
                return mid;
            }
            if (data[mid].compareTo(key) < 0) {
                // if key greater than data[mid], then search from [mid + 1, to]
                from = Math.min(mid + 1, length - 1);
            } else if (data[mid].compareTo(key) > 0) {
                // if key little than data[mid], then search from [from, mid - 1]
                to = Math.max(mid - 1, 0);
            }

            if (from == to) {
                // if from equals to, then check if data[from] equals key
                return (data[from].equals(key)) ? from : -1;
            }
            
            mid = from + ((to - from) + 1) / 2;

        }
        return -1;
    }

}

3.2 插值查找

  插值查找(Interpolation Search)是根据要查找的关键字key与查找表中最大最小记录的关键字比较后的查找方法,其核心在于插值公式 k e y − a [ f r o m ] a [ t o ] − a [ f l o w ] \frac {key-a[from]}{a[to]-a[flow]} a[to]a[flow]keya[from]

  从时间复杂度来看,它也是O(logn),但对于表长较大,而关键字又分布比较均匀的查找表来说,插值查找的平均性能要比折半查找算法的性能要好很多。反之,如果数组分布不均匀,用插值查找未必有优势。

  插值查找是在折半查找的基础上进行优化的,在折半查找中,计算mid的算法为:

   m i d = f r o m + 1 2 ( ( t o − f r o m ) + 1 ) mid = from + \frac {1}{2}((to - from) + 1) mid=from+21((tofrom)+1)

  在插值查找算法中,则是:

   m i d = f r o m + k e y − a [ f r o m ] a [ t o ] − a [ f l o w ] ( ( t o − f r o m ) + 1 ) mid = from + \frac {key-a[from]}{a[to]-a[flow]}((to - from) + 1) mid=from+a[to]a[flow]keya[from]((tofrom)+1)

  因此代码只作少量改动:

/**
 * interpolation search
 * <p>
 * return index in data if searched, else return -1
 *
 * @param data array to search
 * @param key  key to search
 * @return index of key in data
 * @author Korbin
 * @date 2023-04-19 18:30:33
 **/
public int interpolationSearch(int[] data, int key) {

    int length = data.length;

    int from = 0;
    int to = length - 1;

    // if key little than data[0] or key greater than data[length - 1], return -1, means search failed
    if (data[from] > key || data[to] < key) {
        return -1;
    }

    int mid = ((key - data[from]) / (data[to] - data[from])) / 2 * ((to - from) + 1);

    while (from < to) {

        // if data[mid] equals key, then return mid
        if (data[mid] == key) {
            return mid;
        }
        if (data[mid] < key) {
            // if key greater than data[mid], then search from [mid + 1, to]
            from = Math.min(mid + 1, length - 1);
        } else if (data[mid] > key) {
            // if key little than data[mid], then search from [from, mid - 1]
            to = Math.max(mid - 1, 0);
        }

        if (from == to) {
            // if from equals to, then check if data[from] equals key
            return (data[from] == key) ? from : -1;
        }

        mid = from + ((key - data[from]) / (data[to] - data[from])) / 2 * ((to - from) + 1);

    }
    return -1;
}

  调整一下mid的计算方式即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/450556.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LiteFlow规则引擎的入门

文章目录 1、LiteFlow简介2、解决的痛点3、快速开始3.1 引入依赖3.2 配置规则文件的位置3.3 定义组件3.4 指定规则3.5 编写客户端3.6 运行以及说明3.7 其他的组件 4、对于快速开始的思考5、LiteFlow的脚本组件5.1 脚本的定义5.2 脚本的使用5.3 关于脚本使用的思考 6、规则引擎的…

开源Qt Ribbon控件——SARibbon的布局思路及介绍

开源Qt Ribbon控件——SARibbon的布局思路及介绍 SARibbon的布局SARibbon名词定义Office布局模式——SARibbonBar::OfficeStyleWPS布局模式——SARibbonBar::WpsLiteStylepannel的布局行数3行模式2行模式 原文链接&#xff1a;https://blog.csdn.net/czyt1988/article/details/…

scala之基础面向对象

scala 既是面向对象 也是函数式编程 从Java 发展而来&#xff0c;依赖JVM环境 一、 scala 在linux中运行 scala 模式中直接编写运行 scala文件&#xff0c;load执行 scala编译程序 编译 运行 scala java 二、scala 数据类型 基础数据类型 val 不可变变量 函数式编程 …

Excel使用频率超高的20个函数,90%你没用过

上班必学必会的Excel函数&#xff0c;不仅是使用频率最大的&#xff0c;还是告别加班的利器。你会的函数越多&#xff0c;解决问题的思路越广&#xff0c;不再束手束脚。态度决定高度&#xff0c;细节决定成败。要想比别人更优秀&#xff0c;只有在每一件小事上比功夫。 组合、…

json-c交叉编译及库移植

编译后的文件 json-c交叉编译及库移植资源-CSDN文库 json-c开源库是一个用c实现的解析json字段的库&#xff0c;嵌入式领域比较实用的库。 由于应用程序需要&#xff0c;需要找移植这个json-c库&#xff0c;所以这里对该库的移植做个简单说明 json-c开源库是一个用c实现的解…

python基于机器学习模型开发实践kaggle旧金山犯罪案件分类预测模型

旧金山犯罪案件分类本质是一个文本的多分类任务&#xff0c;kaggle官网地址在这里&#xff0c;如下所示&#xff1a; 本文主要是以kaggle比赛数据集为基准&#xff0c;开发实践文本多分类任务。 比赛背景 从 1934 年到 1963 年&#xff0c;旧金山因高犯罪率而臭名昭著。时至今…

opengl绘制三角形

1.绘制两个三角形 GLfloat vertices1[] { 0.5f, 0.5f, 0.0f, 0.5f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f } GLfloat vertices2[] { 0.5f, -0.5f, 0.0f, -0.5f, 0.5f, 0.0f&#xff0c; -0.5f, -0.5f, 0.0f } 也可以用索引的方式&#xff1a; GLfloat vertices[] { 0.5f, 0.5f, 0…

并发编程常见问题复盘

并发编程常见问题复盘 大家好&#xff0c;我是易安&#xff01; 并发编程在计算机科学领域占有举足轻重的地位&#xff0c;它使得程序能够在多个处理器核心上同时执行&#xff0c;从而显著提升程序的性能。然而&#xff0c;并发编程也伴随着许多挑战和问题。这些年来&#xff0…

eacharjs饼状图带百分比

var myChart1 echarts.init(document.getElementById(main1)); myChart1.setOption({title:{text:近30天异常停机的类型TOP5,x:center,y:10px,// textStyle:{// fontSize:12// }},tooltip: {trigger: item//提示 鼠标移动上去},// legend: { // 上面的提示// top: 25%…

端口映射工具PortTunnel

PortTunnel应该是目前最好的端口转发器、端口映射工具(它解决了内外网访问的问题) 可以在我的资源中下载&#xff1a;https://download.csdn.net/download/qq_39569480/87717704 使用该工具前应该保证双方机器网络互通 下面我们模拟一下环境 比如现在有三台机器 A&#xff1a…

Mac环境SpringBoot项目Docker部署(独家完整版)

一、Docker 简介 Docker 是一种开源的容器化平台&#xff0c;允许开发人员将应用程序和所有其依赖项打包成轻量级、可移植的容器&#xff0c;以便在任何地方运行。Docker 的优势和劣势分析如下&#xff1a; 优势: 轻量级:Docker 容器仅包含应用程序及其依赖项&#xff0c;因…

家庭智能吸顶灯一Homekit智能

买灯要看什么因素 好灯具的灯光可以说是家居的“魔术师”&#xff0c;除了实用的照明功能外&#xff0c;对细节的把控也非常到位。那么该如何选到一款各方面合适的灯呢&#xff1f; 照度 可以简单理解为清晰度&#xff0c;复杂点套公式来说照度光通量&#xff08;亮度&#x…

【社区图书馆】二、LED子系统——硬件驱动层

个人主页&#xff1a;董哥聊技术 我是董哥&#xff0c;嵌入式领域新星创作者 创作理念&#xff1a;专注分享高质量嵌入式文章&#xff0c;让大家读有所得&#xff01; 文章目录 1、gpio_led_probe分析1.1 相关数据结构1.1.1 gpio_led_platform_data1.1.2 gpio_leds_priv 1.2 实…

Nextjs 处理 css3 前缀兼容

Nextjs 处理 css3 前缀兼容 虽然css3现在浏览器支持率已经很高了, 但有时候需要兼容一些低版本浏览器,需要给css3加前缀,可以借助插件来自动加前缀, postcss-loader就是来给css3加浏览器前缀的,安装依赖&#xff1a; npm i postcss-loader autoprefixer -Dpostcss-loader&…

前端使用国密SM4进行加密、解密

目录 需求【方法1】 - 使用 sm4util 依赖【方法2】sm4.js引入1. /public/sm4.js2. body 标签上引入该文件3. 使用 - ECB 模式加密 【方法3】1. 本地写 js 文件2. 使用 - ECB 模式加解密 需求 前端/后端使用 国密SM4 进行加密/解密&#xff0c; 【注意】前后端配合加解密时&…

06期:使用 OPTIMIZER_TRACE 窥探 MySQL 索引选择的秘密

这里记录的是学习分享内容&#xff0c;文章维护在 Github&#xff1a;studeyang/leanrning-share。 优化查询语句的性能是 MySQL 数据库管理中的一个重要方面。在优化查询性能时&#xff0c;选择正确的索引对于减少查询的响应时间和提高系统性能至关重要。但是&#xff0c;如何…

scrapy框架爬取某壁纸网站美女壁纸 + MySQL持久化存储

文章目录 准备工作创建项目&#xff1a;设置&#xff08;settings&#xff09; 主程序入口meinv.py思路源代码 items 配置管道pipelines源代码 效果图总结 准备工作 创建项目&#xff1a; scraoy startproject bizhi cd bizhi scrapy genspider meinv bizhi360.com 设置&#…

ROS学习第二十九节——URDF之joint

此处留疑问&#xff0c;link,joint的origin子标签到底是怎么样的一种位置关系&#xff1f;&#xff1f;&#xff1f; https://download.csdn.net/download/qq_45685327/87717336 urdf 中的 joint 标签用于描述机器人关节的运动学和动力学属性&#xff0c;还可以指定关节运动的…

大数据-玩转数据-IDEA创建Maven工程

一、 IDEA集成Maven插件 打开IDEA&#xff0c;进入主界面后点击 file&#xff0c;然后点击 settings,在上面的快捷查找框中输入maven&#xff0c;查找与maven相关的设置&#xff0c;然后点击maven 修改maven的路径&#xff08;使用本地的Maven&#xff09;&#xff0c;以及修…

【流畅的Python学习笔记】2023.4.22

此栏目记录我学习《流畅的Python》一书的学习笔记&#xff0c;这是一个自用笔记&#xff0c;所以写的比较随意 元组 元组其实是对数据的记录&#xff1a;元组中的每个元素都存放了记录中一个字段的数据&#xff0c;外加这个字段的位置。简单试试元组的特性&#xff1a; char…