算法——查找

算法

     数据结构中的算法,指的是数据结构所具备的功能

    解决特定问题的方法,它是前辈们的一些优秀的经验总结

   

    一个算法应该具有以下五个重要的特征:

    有穷性:算法的有穷性是指算法必须能在执行有限个步骤之后终止;

    确切性:算法的每一步骤必须有确切的定义;

    输入项:一个算法有0个或多个输入;

    输出项:一个算法有一个或多个输出,以反映对输入数据加工后的结果。没有输出的算法是毫无意义的;

    可行性:算法中执行的任何计算步骤都是可以被分解为基本的可执行的操作步骤,即每个计算步骤都可以在有限时间内完成(也称之为有效性)

    如何评价一个算法:

        时间复杂度:由于计算机的性能不同,无法准确地衡量出算法执行所需要的时间

            因此我们用算法的执行次数来代表算法的时间复杂度

            一般使用 O(公式) 一般忽略常数

    常见的时间复杂度:

        //  O(1)

        printf("%d",i);

        //  O(logn)

        for(int i=n; i>=0; i/=2)

        {

            printf("%d",i);

        }

        //  O(n)  O(N)

        for(int i=0; i<n; i++)

        {

            printf("%d",i);

        }

        //  O(nlogn)

        for(int i=0; i<n; i++)

        {

            for(int j=n; j>=0; j/=2)

            {

                printf("%d",i);

            }

        }

        //  O(n^2)

        for(int i=0; i<n; i++)

        {

            for(int j=0; j<n; j++)

            {

                printf("%d",i);

            }

        }

    空间复杂度:

        执行一个程序所需要的内存空间大小,是对一个算法在运行过程中临时占用存储空间大小的衡量

        一般只要算法不涉及动态分配的内存以及递归,通常空间复杂度为O(1)

        例如:求第n个斐波那契数列的递归实现算法 空间复杂度O(n)

    注意:对于一个算法而言,其时间复杂度与空间复杂度往往是相互影响的,没有唯一的标准,需要结合实际综合考虑

分治:

    分而治之,把一个大而复杂的问题,分解成很多小而简单的问题,利用计算机强大的计算能力来解决问题

    实现分治的方法:循环、递归

查找算法:

    顺序查找

        对待查找的数据没有要求,从头到尾逐一比较,在小规模的查找中较为常见,查找效率较低

        时间复杂度:O(N)

    二分查找(折半查找)

        待查找的数据必须有序,从数据中间位置开始比较查找,如果中间值比key小,则从左边继续进行二分查找,反之从右边进行。

        时间复杂度:O(logN)      

    块查找(权重查找)

        是一种数据处理的思想,不是一种特定的算法,当数据量非常多时,可以先把数据进行分块处理,然后再根据分块的条件进行查找,例如英文字典

    哈希查找(Hash)

        数据 经过 哈希函数 计算出数据在哈希表中的位置,然后标记位置,方便之后的查找,它的时间复杂度最高可以达到 O(1)

        但是该算法有很大的局限性,不适合负数、浮点型数据、字符型数据的查找,还需要额外申请存储空间,空间复杂度高,是一种典型的以空间换时间的算法

    哈希函数设计方法:

        直接定址法:直接把数据当做哈希表的下标,把哈希表中该下标的位置+1

        数据分析法:分析数据的特点来设计哈希函数,常用的方法是找到最大值和最小值,用 最大值-最小值+1 确定哈希表的长度,使用 数据-最小值 作为哈希表的下标访问哈希表

        平方取中法、折叠法、随机数法,但都无法保证哈希数据的唯一性,出现所谓的哈希冲突,一般使用链表解决

    Hash函数的应用:MD5、SHA-1都属于Hash算法中的应用



 

#include <stdio.h>

#include <stdlib.h>

#include <stdbool.h>

#include <string.h>

#define swap(a,b) {typeof(a) t=(a);(a)=(b);(b)=t;}

#define show_arr(arr,len) \

{for(int i=0;i<len;printf("%d ",arr[i++]));printf("\n");}

//  顺序查找

int order_search(const int* arr,int len,int key)

{

    for(int i=0; i<len; i++)

    {

        if(key == arr[i]) return i;

    }

    return -1;

}

void sort(int* arr,int len)

{

    for(int i=0; i<len-1; i++)

    {

        for(int j=i+1; j<len; j++)

        {

            if(arr[j] < arr[i])

                swap(arr[j],arr[i]);

        }

    }

}

//  循环二分

int binary_search_for(int* arr,int len,int key)

{

    int l = 0, r = len-1;

    while(l <= r)

    {

        int p = (l+r)/2;

        if(arr[p] == key) return p;

        if(arr[p] > key)

            r = p-1;

        else

            l = p+1;

    }

    return -1;

}

int _binary_search(int* arr,int l,int r,int key)

{

    if(l > r) return -1;

   

    int p = (l+r)/2;

    if(arr[p] == key) return p;

    if(key < arr[p])

        return _binary_search(arr,l,p-1,key);

    else

        return _binary_search(arr,p+1,r,key);

}

//  递归二分

int binary_search_recursion(int* arr,int len,int key)

{

    return _binary_search(arr,0,len-1,key);

}

//  哈希查找

bool hash_search(int* arr,int len,int key)

{

    /*

    //  直接定址法

    //  创建哈希表

    int hash[1000000] = {};

    //  标记

    for(int i=0; i<len; i++)

    {

        hash[arr[i]]++;

    }

    //  查找

    return hash[key];

    */

    //  数据分析

    int max = arr[0],min = arr[0];

    for(int i=1; i<len; i++)

    {

        if(arr[i] > max) max = arr[i];

        if(arr[i] < min) min = arr[i];

    }

    //  创建哈希表

    int hash[max-min+1];

    memset(hash,0,sizeof(hash));

    //  标记

    for(int i=0; i<len; i++)

    {

        hash[arr[i]-min]++;

    }

    return hash[key-min];

}

int main(int argc,const char* argv[])

{

    int arr[10] = {};

    for(int i=0; i<10; i++)

    {

        arr[i] = rand()%100;

        printf("%d ",arr[i]);

    }

    printf("\norder_search:%d\n",order_search(arr,10,29));

    sort(arr,10);

    show_arr(arr,10);

    printf("binary_search_for:%d\n",binary_search_for(arr,10,83));

    printf("binary_search_recursion:%d\n",binary_search_recursion(arr,10,77));

    printf("hash_search:%d\n",hash_search(arr,10,77));

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340