c语言的七大查算法,非常值得学习

c语⾔的七⼤查算法,⾮常值得学习
今天带着⼤家学习下,C语⾔七⼤查算法
这⾥我们⾸先看下算法的概念:
算法(Algorithm)是指解题⽅案的准确⽽完整的描述,是⼀系列解决问题的清晰指令,算法代表着⽤系统的⽅法描述解决问题的策略机制。也就是说,能够对⼀定规范的输⼊,在有限时间内获得所要求的输出。
如果⼀个算法有缺陷,或不适合于某个问题,执⾏这个算法将不会解决这个问题。不同的算法可能⽤不同的时间、空间或效率来完成同样的任务。⼀个算法的优劣可以⽤空间复杂度与时间复杂度来衡量。
如下所⽰:C语⾔的七⼤查算法。
1、顺序查
2、⼆分查
3、插值查
4、斐波那契查
5、树表查
6、分块查
7、哈希查
这⾥我们看下查的概念:
查是在⼤量的信息中寻⼀个特定的信息元素,在计算机应⽤中,查是常⽤的基本运算,例如编译程序中符号表的查。
我这⾥简单介绍了常见的七种查算法,说是七种,其实⼆分查、插值查以及斐波那契查都可以归为⼀类——插值查。
插值查和斐波那契查是在⼆分查的基础上的优化查算法。树表查和哈希查。
查算法分类:
1)静态查和动态查;
注:静态或者动态都是针对查表⽽⾔的。动态表指查表中有删除和插⼊操作的表。
2)⽆序查和有序查。
⽆序查:被查数列有序⽆序均可;
有序查:被查数列必须为有序数列。
平均查长度(Average Search Length,ASL):需和指定key进⾏⽐较的关键字的个数的期望值,称为查算法在查成功时的平均查长度。
对于含有n个数据元素的查表,查成功的平均查长度为:ASL = P i*C i的和。
P i:查表中第i个数据元素的概率。
C i:到第i个数据元素时已经⽐较过的次数。
1、顺序查
说明:顺序查适合于存储结构为顺序存储或链接存储的线性表。
基本思想:顺序查也称为线形查,属于⽆序查算法。从数据结构线形表的⼀端开始,顺序扫描,依次将扫描到的结点关键字与给定值k相⽐较,若相等则表⽰查成功;若扫描结束仍没有到关键字等于k的结点,表⽰查失败。
复杂度分析:
查成功时的平均查长度为:(假设每个数据元素的概率相等)
ASL = 1/n(1+2+3+…+n) = (n+1)/2 ;
当查不成功时,需要n+1次⽐较,时间复杂度为O(n);
所以,顺序查的时间复杂度为O(n)。
理论结合实践,我们这⾥直接看顺序查C语⾔实现吧:
//顺序查C语⾔实现
//基本思路:⽤顺序结构存储数据(数组、链表),从前到后依次查询⽬标值,
//            如果发现则返回查到的值,否则返回0.
#include<stdio.h>
int FindBySeq(int *ListSeq, int ListLength, int KeyData);
int main()
{
int TestData[5] = { 34, 35, 26, 89, 56 };
京津冀一体化int retData = FindBySeq(TestData, 5, 89);
printf("retData: %d\n", retData);
return 0;
}
int FindBySeq(int *ListSeq, int ListLength, int KeyData)
{
int tmp = 0;
int length = ListLength;
for (int i = 0; i < ListLength; i++)
{
if (ListSeq[i] == KeyData)
return i;
}
return 0;
}
.
2、⼆分查
说明:元素必须是有序的,如果是⽆序的则要先进⾏排序操作。农村公共产品供给
基本思想:也称为是折半查,属于有序查算法。⽤给定值k先与中间结点的关键字⽐较,中间结点把线形表分成两个⼦表,若相等则查成功;若不相等,再根据k与该中间结点关键字的⽐较结果确定下⼀步查哪个⼦表,这样递归进⾏,直到查到或查结束发现表中没有这样的结点。
复杂度分析:最坏情况下,关键词⽐较次数为log2(n+1),且期望时间复杂度为O(log2n);
注:折半查的前提条件是需要有序表顺序存储,对于静态查表,⼀次排序后不再变化,折半查能得到不错的效率。但对于需要频繁执⾏插⼊或删除操作的数据集来说,维护有序的排序会带来不⼩的⼯作量,那就不建议使⽤。
理论结合实践,我们这⾥直接看⼆分查C语⾔实现吧:
#include<stdio.h>
//⼆分查-C语⾔实现
//基本思路:将排序好的数据存放到数组⾥(不能是链表)
//        这只前中后标签,与中间元素⽐,若⼩于就将后变为原来的中
//        继续计算中,⽐较,循环,直⾄等于中,或循环结束。
int binsearch(int *sortedSeq, int seqLength, int keyData);
int main()
{
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int location;
int target = 4;
location = binsearch(array, 9, target);
printf("%d\n", location);
return 0;
}
int binsearch(int *sortedSeq, int seqLength, int keyData)
{
int low = 0, mid, high = seqLength - 1;
while (low <= high)
{
mid = (low + high) / 2;//奇数,⽆论奇偶,有个值就⾏
if (keyData < sortedSeq[mid])
{
high = mid - 1;//是mid-1,因为mid已经⽐较过了
}
else if (keyData > sortedSeq[mid])
可贵的沉默教学实录{
low = mid + 1;
}
else
{
return mid;
}
}
return -1;
}
3、插值查瓷路
在介绍插值查之前,⾸先考虑⼀个新问题,为什么上述算法⼀定要是折半,⽽不是折四分之⼀或者折更多呢?
打个⽐⽅,在英⽂字典⾥⾯查“apple”,你下意识翻开字典是翻前⾯的书页还是后⾯的书页呢?如果再让你查“zoo”,你⼜怎么查?很显然,这⾥你绝对不会是从中间开始查起,⽽是有⼀定⽬的的往前或往后翻。
同样的,⽐如要在取值范围1 ~ 10000 之间 100 个元素从⼩到⼤均匀分布的数组中查5,我们⾃然会考虑从数组下标较⼩的开始查。
经过以上分析,折半查这种查⽅式,不是⾃适应的(也就是说是傻⽠式的)。⼆分查中查点计算如下:
mid=(low+high)/2, 即mid=low+1/2*(high-low);
通过类⽐,我们可以将查的点改进为如下:
mid=low+(key-a[low])/(a[high]-a[low])*(high-low),
也就是将上述的⽐例参数1/2改进为⾃适应的,根据关键字在整个有序表中所处的位置,让mid值的变化更靠近关键字key,这样也就间接地减少了⽐较次数。
基本思想:基于⼆分查算法,将查点的选择改进为⾃适应选择,可以提⾼查效率。当然,差值查也属于有序查。
注:对于表长较⼤,⽽关键字分布⼜⽐较均匀的查表来说,插值查算法的平均性能⽐折半查要好的多。反之,数组中如果分布⾮常不均匀,那么插值查未必是很合适的选择。
复杂度分析:查成功或者失败的时间复杂度均为O(log2(log2n))。
理论结合实践,我们这⾥直接看插值查C语⾔实现吧:
#include<stdio.h>
//插值查-C语⾔实现
//基本思路:⼆分查改进版,只需改⼀⾏代码。
//        mid=low+(key-a[low])/(a[high]-a[low])*(high-low)
int insertSearch(int *sortedSeq, int seqLength, int keyData);
int main()
{
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int location;
int target = 4;
location = insertSearch(array, 9, target);
printf("%d\n", location);
return 0;
}
int insertSearch(int *sortedSeq, int seqLength, int keyData)
{
int low = 0, mid, high = seqLength - 1;
while (low <= high)
{
mid = low + (keyData - sortedSeq[low]) / (sortedSeq[high] - sortedSeq[low]);
if (keyData < sortedSeq[mid])
{
high = mid - 1;//是mid-1,因为mid已经⽐较过了
}
else if (keyData > sortedSeq[mid])
{
low = mid + 1;
}
毛远建
else
{
return mid;
}
}
return -1;
飞虎续集
}
关注获取更多嵌⼊式软件开发学习⽅法

本文发布于:2024-09-22 16:32:40,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/397696.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:查找   算法   数据   有序   关键字   复杂度   时间   顺序
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议