700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 顺序查找的递归算法 c语言 (一)算法--查找算法顺序查找和二分查找(递归和非递归

顺序查找的递归算法 c语言 (一)算法--查找算法顺序查找和二分查找(递归和非递归

时间:2023-10-30 07:46:38

相关推荐

顺序查找的递归算法 c语言 (一)算法--查找算法顺序查找和二分查找(递归和非递归

我们抛开二分查找算法,如果有这样的一个需求,需要在一些数字中找出有没有某个数字,我们应该怎么做?

1 首先我们会想到用什么数据结构存放这些数?

数据结构就是计算机存储组织、组织数据的方式。可以这样理解,生活中我们穿的衣服需要放到一个地方,衣服可以放到衣橱中,也可以放到行李箱中,也可以放到衣架中,这里的衣架、衣橱、和行李箱及是衣服的存放结构。所以我们在查找某一个数字是否在一堆数字中的时候,我们要把数据放到数据结构中,不同的数据结构有不同的优势,就像衣服放到不同的“存储”中,会有不同的优势。而精心选择的数据结构可以带来更高的运行或者存储效率。

计算机中有哪些数据结构呢?

常见的数据结构有数组(Array)、堆栈(Stack)、队列(Queue)、链表(Linked List)、树(Tree)、图(Graph)、堆(Heap)、散列表(Hash)。

具体的数据结构以及优势就不再这里介绍了,以后会一一介绍。

而java语言常用的数据结构有数组,list,set,map。list实际上也是数组结构,不太复杂和确定长度下,使用数组的效率会高些,数组是确定长度的。list的值可以重复,set的值不可以重复,map是一种键值对,键可以是多种类型的与值形成对应关系。

我们是在固定一些数字中查找到我们想要的数字所在位置,当我们需要存储或处理一系列数据,数组就可以充当这样的角色,它的内存是相连的数据,并且在栈中引用只有一个,如果不用数组,就要一个一个的声明,浪费存储空间,显然不合理,所以我们在这里用数组结构,而java的其他数据结构分别适合在哪些场景中使用呢?在这里就不介绍了,后续文章会总结。

2 顺序查找

抛开所学,我们最简单和最”笨”的方式就是挨个的查找和比较,看是不是我想要的那个key。这就是顺序查找。java代码如下

条件:无序或有序元素。

原理:按顺序比较每个元素,直到找到关键字为止。

时间复杂度:O(n)

/**

*顺序查找

*@paramsrcArray

*/

publicstaticintorderSearch(intsrcArray[],intkey){

for(inti=0;i

if(key==srcArray[i]){

returni;

}

}

return-1;

}

3 二分查找法

当我们的数字是有序的情况下,可以采用顺序查找法,也可以采用二分查找法,而人们发现发了在元素有序的时候,使用二分查找法效率更高。大概是谁想出来的二分查找法的人物不再说明,说一下二分查找思想。

条件:有序元素

思想:

3.1 不像顺序查找那样,我们取得数组中间的数字,如果正好是我们要查找的元素,则搜索过程结束;

3.2 中间的元素不是我们想要的元素,我们比较中间元素和我们想要元素的大小

如果中间元素大于/小于中间元素,则我们在大于/小于的那一半查找,而且和开始一样从中间的元素开始比较(也就是把剩下的一半当做新的开始)。

3.3 直到某一步比较,找到我们的key,返回该key所在的数组下标。

3.4 如果都没有找到,存放数组低地址的变量大于高地址变量时,则查找结束,说明该有序序列中没有我们想找到的。

复杂度:O(logn)

从解决问题思想到程序实现,这里面有几个点。

1)取数组中间位置,第一次可以是数组元素长度/2,第二次我们如何从数组剩下的一半中取中间位置?以及第三次呢?也就是每次我们都要知道”新数组”的开始和结尾,以及中间位置;所以我们可以定义两个数组下标变量,low 和high(内存中的地址大小),以及mid(每次的中间下标),这样通过移动他们来做到轮询,有些类似c语言中的指针变量。

2)怎么结束比较?每次都找不到,直到数组的一半已经没有元素了,也就是low指向的数组地址已经大于high指向的数组地址,说明不存在。java代码如下,之后再逐步分析代码

非递归方式实现

/**

*二分查找普通实现。

*@paramsrcArray有序数组

*@paramkey查找元素

*@return不存在返回-1,存在返回对应的数组下标

*/

publicstaticintbinSearch(intsrcArray[],intkey){

intmid=srcArray.length/2;

if(key==srcArray[mid]){

returnmid;

}

intlow=0;

inthigh=srcArray.length-1;

while(low<=high){

mid=(high-low)/2+low;

if(key

high=mid-1;

}elseif(key>srcArray[mid]){

low=mid+1;

}else{

returnmid;

}

}

return-1;

}

递归方式实现

/**

*二分查找递归实现。

*@paramsrcArray有序数组

*@paramlow数组低地址下标

*@paramhigh数组高地址下标

*@paramkey查找元素

*@return查找元素不存在返回-1,存在返回对应的数组下标

*/

publicstaticintbinSearch(intsrcArray[],intlow,inthigh,intkey){

intmid=(high-low)/2+low;

if(srcArray[mid]==key){

returnmid;

}

if(low>=high){

return-1;

}elseif(key>srcArray[mid]){

returnbinSearch(srcArray,mid+1,high,key);

}elseif(key

returnbinSearch(srcArray,low,mid-1,key);

}

return-1;

}

main方法

publicstaticvoidmain(String[]args){

intsrcArray[]={3,6,11,17,21,23,28,30,81,89,99};

System.out.println(binSearch(srcArray,0,srcArray.length-1,222));

System.out.println(binSearch(srcArray,222));

System.out.println(orderSearch(srcArray,5));

}

执行过程图,大概的画了一下,如下图。

两种实现方式,一种是普通实现方式,一种是递归思想实现方式,递归关注一个核心,而把变化的部分通过递归变量的改变而变化。

看了之前写过二分查找算法,但是过了一段时间发现又会忘记,是当时没有真正理解吧,之前的简单粗暴,也感谢网友们当时指出问题:/lovesummerforever/article/details/24588989

总结:

1知识一定要变成自己的理解,才是自己的,不然会是瞬时记忆,都会还给书本。

2 孤立的知识很难被记住,我们想要成块的去理解,不要只学习其中的断层,知道学习这个技术在知识体系中的什么位置,和其他知识的联系。

3 晦涩难懂的东西要追本溯源,因为这个技术一定是从简单演变而来的,是多个简单的叠加过程,最终我们才看到成型,必须要思考是怎么衍变的。(例如文字的发展史)

4 技术来自生活却高于生活,当不懂的时候,想想生活中的一些离我们近的事物,都是如出一辙的。

顺序查找的递归算法 c语言 (一)算法--查找算法顺序查找和二分查找(递归和非递归方式)...

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。