导航:首页 > 源码编译 > 对查找算法的个人总结

对查找算法的个人总结

发布时间:2022-12-11 12:51:50

⑴ 什么是查找法

算法思想:

将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小于该中点元素,则将待查序列缩小为左半部分,否则为右半部分。通过一次比较,将查找区间缩小一半。

折半查找是一种高效的查找方法。它可以明显减少比较次数,提高查找效率。但是,折半查找的先决条件是查找表中的数据元素必须有序。

算法步骤描述:

step1 首先确定整个查找区间的中间位置
mid = ( left + right )/ 2

step2 用待查关键字值与中间位置的关键字值进行比较;

若相等,则查找成功

若大于,则在后(右)半个区域继续进行折半查找

若小于,则在前(左)半个区域继续进行折半查找
Step3 对确定的缩小区域再按折半公式,重复上述步骤。最后,得到结果:要么查找成功, 要么查找失败。
折半查找的存储结构采用一维数组存放。

折半查找算法举例

对给定数列(有序){ 3,5,11,17,21,23,28,30,32,50},按折半查找算法,查找关键字值为30的数据元素。

折半查找的算法讨论:

优点: ASL≤log2n,即每经过一次比较,查找范围就缩小一半。经log2n 次计较就可以完成查找过程。

缺点:因要求有序,所以要求查找数列必须有序,而对所有数据元素按大小排序是非常费时的操作。另外,顺序存储结构的插入、删除操作不便利。

考虑:能否通过一次比较抛弃更多的部分(即经过一次比较,使查找范围缩得更小),以达到提高效率的目的。……?

可以考虑把两种方法(顺序查找和折半查找)结合起来,即取顺序查找简单和折半查找高效之所长,来达到提高效率的目的?实际上这就是分块查找的算法思想。

例如:[问题分析] 由于数据按升序排列,故用折半查找最快捷.
program binsearch;
const max=10;
var num:array[1..max] of integer;
i,n:integer;
procere search(x,a,b:integer);
var mid:integer;
begin
if a=b then
if x=num[a] then writeln('Found:',a) else writeln('Number not found')
else begin
mid:=(a+b) div 2;
if x>num[mid] then search(x,mid,b);
if x<num[mid] then search(x,a,mid);
if x=num[mid] then writeln('Found:',mid);
end;
end;
begin
write('Please input 10 numbers in order:');
for i:=1 to max do read(num);
write('Please input the number to search:');
readln(n);
search(n,1,max);
end.

Java风格的代码举例:
//使用折半法进行查找
int getIndex(int[] nList, int nCount, int nCode) {
int nIndex = -1;
int jMin = 0;
int jMax = nCount - 1;
int jCur = (jMin+jMax)/2;
do
{
if(nList[jCur] > nCode) {
jMax--;
} else if(nList[jCur] < nCode) {
jMin++;
} else if(nList[jCur] == nCode) {
nIndex = jCur;
break;
}
jCur = (jMin + jMax)/2;
} while(jMin < jMax);

return nIndex;
}

二分查找的性能说明

虽然二分查找的效率高,但是要将表按关键字排序。而排序本身是一种很费时的运算。既使采用高效率的排序方法也要花费 O(n lg n) 的时间。
二分查找只适用顺序存储结构。为保持表的有序性,在顺序结构里插入和删除都必须移动大量的结点。因此,二分查找特别适用于那种一经建立就很少改动、而又经常需要查找的线性表。
对那些查找少而又经常需要改动的线性表,可采用链表作存储结构,进行顺序查找。链表上无法实现二分查找

二分查找的C#实现代码:
using System;
using System.Collections.Generic;
using System.Text;
namespace BinschDemo
{
public class BinschDemo
{
public static int Binsch(int[] a, int key)
{
int low = 1;
int high = a.Length;
while (low <= high)
{
int mid = (low + high) / 2;
if (key == a[mid])
{
return mid; //返回找到的索引值
}
else
{
if (key < a[mid])
high = mid - 1;
else
low = mid + 1;
}
}
return -1; //查找失败
}
static void Main(string[] args)
{
Console.WriteLine("请输入10个递增数字: ");
int[] list = new int[10];
for (int i = 0; i < 10; i++)
{
Console.Write("数字 : ", i);
list = Convert.ToInt32(Console.ReadLine());
}
Console.Write("请输入一个你要查找的数字:");
int find = Convert.ToInt32(Console.ReadLine());
int result = Binsch(list, find);
Console.WriteLine(result);
}
}
}

分块查找又索引查找,它主要用于“分块有序”表的查找。所谓“分块有序”是指将线性表L(一维数组)分成m个子表(要求每个子表的长度相等),且第i+1个子表中的每一个项目均大于第i个子表中的所有项目。“分块有序”表应该包括线性表L本身和分块的索引表A。因此,分块查找的关键在于建立索引表A。
(1)建立索引表A(二维数组)
索引表包括两部分:关键字项(子表中的最大值)和指针项(子表的第一项在线性表L中位置)
索引表按关键字有序的。
例如:线性表L(有序)为:1 2 3 4 5 6 7 8 9 10 11 12
分成m=3个子表:{1 2 3 4} {5 6 7 8} {9 10 11 12}
索引表A:二维数组:第一列为每个子表的最大值 ,第二列为每个子表的起始地址
即: 4 0
8 4
12 8
(2)利用索引表A,确定待查项X所在的子表(块)。
(3)在所确定的子表中可以用“折半查找”法搜索待查项X;若找到则输出X;否则输出未找到信息。

⑵ 二分查找算法实现(图解)与实例

当我们要从一个序列中查找一个元素的时候,二分查找是一种非常快速的查找算法,二分查找又叫折半查找。

它对要查找的序列有两个要求,一是该序列必须是有序的(即该序列中的所有元素都是按照大小关系排好序的,升序和降序都可以,本文假设是升序排列的),二是该序列必须是顺序存储的。

如果一个序列是无序的或者是链表,那么该序列就不能进行二分查找。之所以被查找的序列要满足这样的条件,是由二分查找算法的原理决定的。

二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好;其缺点是要求待查表为有序表,且插入删除困难。因此,折半查找方法适用于不经常变动而查找频繁的有序列表。

二分查找能应用于任何类型的数据,只要能将这些数据按照某种规则进行排序。然而,正因为它依赖于一个有序的集合,这使得它在处理那些频繁插入和删除操作的数据集时不太高效。这是因为,对于插入和操作来说,为了保证查找过程正常进行,必须保证数据集始终有序。相对于查找来说,维护一个有序数据集的代价更高。此外,元素必须存储在连续的空间中。因此,当待搜索的集合是相对静态的数据集时,此时使用二分查找是最好的选择。

二分查找算法的原理如下:

二分查找之所以快速,是因为它在匹配不成功的时候,每次都能排除剩余元素中一半的元素。因此可能包含目标元素的有效范围就收缩得很快,而不像顺序查找那样,每次仅能排除一个元素。

二分查找法实质上是不断地将有序数据集进行对半分割,并检查每个分区的中间元素。

此实现过程的实施是通过变量left和right控制一个循环来查找元素(其中left和right是正在查找的数据集的两个边界值)。

二分查找的时间复杂度取决于查找过程中分区数可能的最大值。对于一个有n个元素的数据集来说,最多可以进行O(㏒₂n)次分区。对于二分查找,这表示最终可能在最坏的情况下执行的检查的次数:例如,在没有找到目标时。所以二分查找的时间复杂度为O(㏒₂n)。

参考:
https://www.html.cn/qa/other/23018.html

https://www.cnblogs.com/idreamo/p/9000762.html

⑶ 常用查找算法

查找算法可分为两种: 无序查找 有序查找 ,顾名思义,无序查找就是查找数列中的数是无序的,有序查找要求所查找数列是已经按照一定的规律排好序了,常见算法中大多都是无序查找。下面一一介绍几种常见的查找算法。

顾名思义,就是将所查找数列构建成一颗树,其中最常见的是构建成一颗 二叉查找树(左子节点的值均小于父节点的值,右子节点的值均大于父节点的值) ,然后通过遍历比较得出查找结果。

⑷ 基本算法——二分查找算法

    二分查找也称折半查找(Binary Search),它是一种效率较高的查找方法。但是,折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。

1.条件

(1)必须采用 顺序存储结构 。

(2)必须按关键字大小有序排列。

2.步奏

(1)首先,假设表中元素是按升序排列,将表中间位置记录的 关键字 与查找关键字比较,如果两者相等,则查找成功;

(2)否则利用中间位置 记录 将表分成前、后两个子表,如果中间位置记录的关键字大于查找关键字,则进一步查找前一子表,否则进一步查找后一子表;

(3)重复以上过程,直到找到满足条件的 记录 ,使查找成功,或直到子表不存在为止,此时查找不成功。

3.举例

    有一组元素{1,2,3,4,5,6,7,8,9},如何查到元素为3。

(1)找到数组中中间元素值5,不等于3,所以把数组分为{1,2,3,4},{5,6,7,8,9};

(2)因为5大于3,所以3在前一个数组{1,2,3,4}中查找,中间变量2,3比2大,所以在{3,4}中查询;

(3)查询到3=3,成功。

4.复杂度

     最好的情况下,1次查询成功;最坏的情况下,查询到最后两个数或者最后也查不到相等数,时间复杂度为O(log2n)。

⑸ C语言编写数据结构查找算法

实验五 查找的实现
一、 实验目的
1.通过实验掌握查找的基本概念;
2.掌握顺序查找算法与实现;
3.掌握折半查找算法与实现。
二、 实验要求
1. 认真阅读和掌握本实验的参考程序。
2. 保存程序的运行结果,并结合程序进行分析。
三、 实验内容
1、建立一个线性表,对表中数据元素存放的先后次序没有任何要求。输入待查数据元素的关键字进行查找。为了简化算法,数据元素只含一个整型关键字字段,数据元素的其余数据部分忽略不考虑。建议采用前哨的作用,以提高查找效率。
2、查找表的存储结构为有序表,输入待查数据元素的关键字利用折半查找方法进行查找。此程序中要求对整型量关键字数据的输入按从小到大排序输入。
一、顺序查找
顺序查找代码:
#include"stdio.h"
#include"stdlib.h"
typedef struct node{
intkey;
}keynode;
typedef struct Node{
keynoder[50];
intlength;
}list,*sqlist;
int Createsqlist(sqlist s)
{
inti;
printf("请输入您要输入的数据的个数:\n");
scanf("%d",&(s->length));
printf("请输入您想输入的%d个数据;\n\n",s->length);
for(i=0;i<s->length;i++)
scanf("%d",&(s->r[i].key));
printf("\n");
printf("您所输入的数据为:\n\n");
for(i=0;i<s->length;i++)
printf("%-5d",s->r[i].key);
printf("\n\n");
return1;
}
int searchsqlist(sqlist s,int k)
{
inti=0;
s->r[s->length].key=k;
while(s->r[i].key!=k)
{

i++;
}
if(i==s->length)
{
printf("该表中没有您要查找的数据!\n");
return-1;
}
else
returni+1;
}
sqlist Initlist(void)
{
sqlistp;
p=(sqlist)malloc(sizeof(list));
if(p)
returnp;
else
returnNULL;
}
main()
{
intkeyplace,keynum;//
sqlistT;//
T=Initlist();
Createsqlist(T);
printf("请输入您想要查找的数据的关键字:\n\n");
scanf("%d",&keynum);
printf("\n");
keyplace=searchsqlist(T,keynum);
printf("您要查找的数据的位置为:\n\n%d\n\n",keyplace);
return2;
}
顺序查找的运行结果:
二、折半查找
折半查找代码:
#include"stdio.h"
#include"stdlib.h"
typedef struct node{
intkey;
}keynode;
typedef struct Node{
keynoder[50];
intlength;
}list,*sqlist;
int Createsqlist(sqlist s)
{
inti;
printf("请输入您要输入的数据的个数:\n");
scanf("%d",&(s->length));
printf("请由大到小输入%d个您想输入的个数据;\n\n",s->length);
for(i=0;i<s->length;i++)
scanf("%d",&(s->r[i].key));
printf("\n");
printf("您所输入的数据为:\n\n");
for(i=0;i<s->length;i++)
printf("%-5d",s->r[i].key);
printf("\n\n");
return1;
}
int searchsqlist(sqlist s,int k)
{
intlow,mid,high;
low=0;
high=s->length-1;
while(low<=high)
{
mid=(low+high)/2;
if(s->r[mid].key==k)
returnmid+1;
elseif(s->r[mid].key>k)
high=mid-1;
else
low=mid+1;
}
printf("该表中没有您要查找的数据!\n");
return-1;
}
sqlist Initlist(void)
{
sqlistp;
p=(sqlist)malloc(sizeof(list));
if(p)
returnp;
else
returnNULL;
}
main()
{
intkeyplace,keynum;//
sqlistT;//
T=Initlist();
Createsqlist(T);
printf("请输入您想要查找的数据的关键字:\n\n");
scanf("%d",&keynum);
printf("\n");
keyplace=searchsqlist(T,keynum);
printf("您要查找的数据的位置为:\n\n%d\n\n",keyplace);
return2;
}
折半查找运行结果:
三、实验总结:
该实验使用了两种查找数据的方法(顺序查找和折半查找),这两种方法的不同之处在于查找方式和过程不同,线性表的创建完全相同,程序较短,结果也一目了然。

⑹ 最好的查找算法是什么

没有最好只有更好
对不同特征的数据也有不同的查找算法,所有的查找算法都是针对某一特征的数据进行优化的,比如用散列表查找很快的数据用二分发就不一定快,散列表用不同的哈希算法查找性能也大不相同。

⑺ 数学建模算法总结

无总结反省则无进步

写这篇文章,一是为了总结之前为了准备美赛而学的算法,而是将算法罗列并有几句话解释方便以后自己需要时来查找。

数学建模问题总共分为四类:

1. 分类问题 2. 优化问题 3. 评价问题 4. 预测问题

我所写的都是基于数学建模算法与应用这本书

一 优化问题

线性规划与非线性规划方法是最基本经典的:目标函数与约束函数的思想

现代优化算法:禁忌搜索;模拟退火;遗传算法;人工神经网络

模拟退火算法:

简介:材料统计力学的研究成果。统计力学表明材料中不同结构对应于粒子的不同能量水平。在高温条件下,粒子的能量较高,可以自由运动和重新排列。在低温条件下,粒子能量较低。如果从高温开始,非常缓慢地降温(此过程称为退火),粒子就可以在每个温度下达到热平衡。当系统完全被冷却时,最终形成处于低能状态的晶体。

思想可用于数学问题的解决 在寻找解的过程中,每一次以一种方法变换新解,再用退火过程的思想,以概率接受该状态(新解) 退火过程:概率转化,概率为自然底数的能量/KT次方

遗传算法: 遗传算法是一种基于自然选择原理和自然遗传机制的搜索算法。模拟自然界中的生命进化机制,在人工系统中实现特定目标的优化。

遗传算法的实质是通过群体搜索技术(?),根据适者生存的原则逐代进化,最终得到最优解或准最优解。

具体实现过程(P329~331)

* 编码

* 确定适应度函数(即目标函数)

* 确定进化参数:群体规模M,交叉概率Pc,变异概率Pm,进化终止条件

* 编码

* 确定初始种群,使用经典的改良圈算法

* 目标函数

* 交叉操作

* 变异操作

* 选择

改良的遗传算法

两点改进 :交叉操作变为了以“门当户对”原则配对,以混乱序列确定较差点位置 变异操作从交叉操作中分离出来

二 分类问题(以及一些多元分析方法)

* 支持向量机SVM

* 聚类分析

* 主成分分析

* 判别分析

* 典型相关分析

支持向量机SVM: 主要思想:找到一个超平面,使得它能够尽可能多地将两类数据点正确分开,同时使分开的两类数据点距离分类面最远

聚类分析(极其经典的一种算法): 对样本进行分类称为Q型聚类分析 对指标进行分类称为R型聚类分析

基础:样品相似度的度量——数量化,距离——如闵氏距离

主成分分析法: 其主要目的是希望用较少的变量去解释原来资料中的大部分变异,将掌握的许多相关性很高的变量转化成彼此相互独立或不相关的变量。通常是选出比原始变量个数少,能解释大部分资料中的变异的几个新变量,及主成分。实质是一种降维方法

判别分析: 是根据所研究的个体的观测指标来推断个体所属类型的一种统计方法。判别准则在某种意义下是最优的,如错判概率最小或错判损失最小。这一方法像是分类方法统称。 如距离判别,贝叶斯判别和FISHER判别

典型相关分析: 研究两组变量的相关关系 相对于计算全部相关系数,采用类似主成分的思想,分别找出两组变量的各自的某个线性组合,讨论线性组合之间的相关关系

三 评价与决策问题

评价方法分为两大类,区别在于确定权重上:一类是主观赋权:综合资讯评价定权;另一类为客观赋权:根据各指标相关关系或各指标值变异程度来确定权数

* 理想解法

* 模糊综合评判法

* 数据包络分析法

* 灰色关联分析法

* 主成分分析法(略)

* 秩和比综合评价法 理想解法

思想:与最优解(理想解)的距离作为评价样本的标准

模糊综合评判法 用于人事考核这类模糊性问题上。有多层次模糊综合评判法。

数据包络分析法 是评价具有多指标输入和多指标输出系统的较为有效的方法。是以相对效率为概念基础的。

灰色关联分析法 思想:计算所有待评价对象与理想对象的灰色加权关联度,与TOPSIS方法类似

主成分分析法(略)

秩和比综合评价法 样本秩的概念: 效益型指标从小到大排序的排名 成本型指标从大到小排序的排名 再计算秩和比,最后统计回归

四 预测问题

* 微分方程模型

* 灰色预测模型

* 马尔科夫预测

* 时间序列(略)

* 插值与拟合(略)

* 神经网络

微分方程模型 Lanchester战争预测模型。。

灰色预测模型 主要特点:使用的不是原始数据序列,而是生成的数据序列 优点:不需要很多数据·,能利用微分方程来充分挖掘系统的本质,精度高。能将无规律的原始数据进行生成得到规律性较强的生成序列。 缺点:只适用于中短期预测,只适合指数增长的预测

马尔科夫预测 某一系统未来时刻情况只与现在状态有关,与过去无关。

马尔科夫链

时齐性的马尔科夫链

时间序列(略)

插值与拟合(略)

神经网络(略)

⑻ 标题讨论1.如何评价一个查找算法

评价一个查找算法是用平均查找长度来进行评价。使用平均查找长度,即关键字的平均比较次数来评价查找算法,这个值越大,对应的查找算法的效率越低。

⑼ 查找--有序表查找(折半查找,插值查找,斐波拉契查找)

引言
如果待查找的数组是有序的,那么此时的查找就是有序表查找,这对于查找的帮助是很大的。属于有序表查找的有:折半查找(二分查找)、插值查找以及斐波那契查找。

1. 折半查找
折半查找又称为二分查找,是一种效率较高的查找算法。折半查找的先决条件是查找表中的数据元素排列必须是有序的。折半查找先以有序数列的中点位置为比较对象,如果要找的元素值小于中点位置元素,则将待查序列缩小为左半部分,否则为右半部分。通过一次比较,可以将查找的区间缩小一半,每次比较,都可以将当前查找范围缩小至一般,可以明显的减少比较的次数,提高查找效率。
时间复杂度:O(logn)
算法实现:

2. 插值查找
插值查找是二分查找演化而来,相比于二分查找(折半),该算法考虑的是每次折的时候折多少,即不一定是1/2;如在一本字典中找"abstract"这个单词,我们自己来操作肯定是先翻到字典开始的那一小部分,而不是从字典的中间开始进行折半查找。

在二分查找中mid=(low+high)/2=low+1/2*(high-low),插值查找就是对1/2(系数,或者说比例)进行改变,它将1/2变成 (key - array[low])/(array[high] - array[low]),其实就是计算线性比例。

时间复杂度:O(logn)
因为插值查找是依赖线性比例的,如果当前数组分布不是均匀的,那么该算法就不合适。

算法实现:

3. 斐波那契查找
根据前面二分查找以及插值查找来看,有序表上的查找的关键就是如何分割当前查找的区域(二分查找对半分割,差值查找按线性比例分割),说到分割,还有一个着名的分割方式就是黄金分割。

斐波那契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、····,在数学上,斐波那契被递归方法如下定义:F(1)=1,F(2)=1,F(n)=f(n-1)+F(n-2) (n>=2)。该数列越往后相邻的两个数的比值越趋向于黄金比例值(0.618)

所以我们可以根据斐波那契数列对当前区域进行分割 :)

查找算法:在斐波那契数列找一个等于略大于查找表中元素个数的数F(n),将原查找表扩展为长度为F(n)(如果要补充元素,则补充重复最后一个元素,直到满足数组元素个数为F(n)个元素),完成后进行斐波那契分割,即F(n)个元素分割为前半部分F(n-1)个元素,后半部分F(n-2)个元素,找出要查找的元素在那一部分并递归,直到找到。
时间复杂度:O(logn),平均性能优于二分查找。
算法实现:

结束语
以上三种查找算法中,都依赖于顺序表,三者的区别本质上就是分割点选的不同。在分割点的选择中,折半查找 mid=(low+high)/2是加法与除法运算;插值查找mid = low+(key-array[low])/(array[high]-array[low])*(high-low)是复杂的四则运算;斐波那契查找mid=low+fib[k-1]-1是简单的加减运算。在海量数据查找过程中细微的差别会影响最终的效率。

三种查找算法,各有优劣,实际开发可以根据数据的特点综合考虑再做出选择。

阅读全文

与对查找算法的个人总结相关的资料

热点内容
单片机高电平驱动 浏览:115
ios多选文件夹 浏览:907
加强行车调度命令管理 浏览:241
服务器已禁用什么意思 浏览:148
部队命令回复 浏览:753
神奇宝贝服务器地图怎么设置 浏览:380
加密算法输出固定长度 浏览:862
程序员去重庆还是武汉 浏览:121
服务器如何撤销网页登录限制 浏览:980
微信公众平台php开发视频教程 浏览:628
怎么看苹果授权绑定的app 浏览:255
压缩机单级压缩比 浏览:380
linux测试php 浏览:971
什么时候梁旁边需要加密箍筋 浏览:40
微信清粉软件源码 浏览:717
matlabdoc命令 浏览:550
如何去ping服务器 浏览:75
ecshop安装php55 浏览:817
javaword库 浏览:958
php图片路径数据库中 浏览:488