惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
有赞技术团队
有赞技术团队
L
LangChain Blog
C
Check Point Blog
博客园 - 【当耐特】
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
V2EX
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
GbyAI
GbyAI
美团技术团队
博客园 - 司徒正美
Google DeepMind News
Google DeepMind News
WordPress大学
WordPress大学
aimingoo的专栏
aimingoo的专栏
S
SegmentFault 最新的问题
A
About on SuperTechFans
Blog — PlanetScale
Blog — PlanetScale
Hugging Face - Blog
Hugging Face - Blog
博客园 - 叶小钗
腾讯CDC
B
Blog
G
Google Developers Blog
The Cloudflare Blog
P
Proofpoint News Feed

博客园 - 蓝之风

解决:gradle 前言中不允许有内容 【LINQ标准查询操作符总结】之聚合操符 RxJS 中的创建操作符 项目管理(1) 什么是项目? 数据库表数据统计及数据表的数据大小统计SQL C# 中一些类关系的判定方法 Windows Azure NotificationHub+Firebase Cloud Message 实现消息推动(付源码) Windows 下安装RabbitMQ服务器及基本配置 【设计模式】组合模式实现二叉树先序遍历,中序遍历和后序遍历 【设计模式】组合模式 Composite Pattern 【设计模式】桥接模式 Bridge Pattern 在VS 2017 下创建 Xamarin NuGet Package 【设计模式】适配器模式 Adapter Pattern 【设计模式】原型模式 Pototype Pattern 三个基本排序算法执行效率比较(冒泡排序,选择排序和插入排序) 【设计模式】单例模式 Singleton Pattern 【设计模式】建造者模式 Builder Pattern 【设计模式】抽象工厂模式 Abstract Factory Pattern 【设计模式】工厂方法模式 Factory Method Pattern
基础查找算法(顺序无序查找算法和递归二叉查找算法)
蓝之风 · 2018-08-06 · via 博客园 - 蓝之风

一、顺序无序查找算法

顺序查找算法很简单也很好理解,就是在一个序列中从前往后遍历集合直到查到目标值为止。通常查找最大值和最小值都是这种方法。

1、顺序查找的一般实现:

public static int SqSearch(int[] source, int target)
{
    for (int i = 0; i < source.Length; i++)
    {
        if (source[i] == target)
        {
            return i;
        }
    }

    return -1;
}

查找最大值

public static int FindMax(int[] source)
{
    int max=source[0];
    for(int i=1;i<source.Length;i++){
        if(max<source[i]){
            max=source[i];                   
        }
    }
    return max;
}

查找最小值

public static int FindMin(int[] source)
{
    int min = source[0];
    for (int i = 1; i < source.Length; i++)
    {
        if (source[i] < min)
        {
            min = source[i];
        } 
    }

    return min;
}

顺序查找的特点是查找效率依赖于元素所在的位置,如果查找元素在第一个,那就是秒查,效率非常高,如果查询元素在最后一个那么就要遍历整个集合,效率就低了。

改变集合数据加快查询效率

根据“2-8”定律,一般情况下20%的数据是hot data, 80%是cool data, 数据也符合现在的财富“2-8 ”定律,因此在查询数据的时候可以将每次查到的数据移动到头部的20%,这样就会将hot data 放在最前面这样就可以提高效率。

public static int Hot20SqSearch(int[] source, int target)
{
    for (int i = 0; i < source.Length; i++)
    {
        if (source[i] == target)
        {
            if (i > source.Length * 0.2)
            {
                var temp = source[0];
                source[0] = source[i];
                source[i] = temp;
            }
            return i;
        }
    }

    return -1;
}

这样会解决部分问题,但是还是有问题,如果每次都查的是头部20%的数据没有问题,但是如果查到一个后面的80%的数据,就会将第一个hot data交换到后面的的位置了,下次查询就又慢了的问题,还有一种方式就是每次查到的词只向前移动一个位置,如果是高频词查的多了必然会跑到最前面,下面是这种改变查询结果的代码:

public static int HotSwapSqSearch(int[] source, int target)
{
    for (int i = 0; i < source.Length; i++)
    {
        if (source[i] == target)
        {
            if (i > 0)
            {
                var temp = source[i-1];
                source[i-1] = source[i];
                source[i] = temp;
            }
            return i;
        }
    }

    return -1;
}

现在手机上的中文输入法,就会就和这个类似,让输入的高频词放在输入法的最前面方便输入文字。

二、二叉查找算法

二叉查找算法是基于有序序列的一种查找算法,上面的顺序查找算法是无序的。二叉查找的特点是每次通过和中间值的比较来决定是查找中间值左边部分,还是查询右边部分。和电视上的猜商品的价格游戏是一样的,根据“一半”的策略缩小范围,最终猜到商品的价格,下面是典型的代码:

public static int BinSearch(int[] source, int target)
{
    int left = 0, right = source.Length-1,middle;
    while (left <= right)
    {
        middle = (left + right) / 2;
        if (source[middle] == target)
        {
            return middle;
        }
        else
        {
            if (source[middle] > target)
            {
                right = middle - 1;
            }
            else
            {
                left = middle + 1;
            }
        }
    }
    return -1;
}

三、递归实现二叉算法

二叉查找每次都是给定一个集合并给定一个最小索引和最大索引,不断的缩小集合的大小,进而缩小查找范围,直至查到或者集合中没有元素了。因此这也是一个标准的递归算法,用递归实现二叉查找:

public static int RBinSearch(int[] source, int target, int left, int right)
{
    if (left > right)
    {
        return -1;
    }
    else
    {
        int middle = (int)(left + right) / 2;
        if (source[middle] == target)
        {
            return middle;
        }
        else
        {
            if (source[middle] > target)
            {
                return RBinSearch(source, target, left, right - 1);
            }
            else
            {
                return RBinSearch(source, target, left + 1, right);
            }
        }
    }
}

这几个基础的查找算法,在平时开发的过程中经常会用到。现在的框架做的事情太多了,像这些基础的算法,可能只有在学校或者考试的时候才能用上,但是这些都是基础,只有掌握了这些基础知识才能更好的使用框架或者类库提供的方法。