关于查找(二分查找)和排序(冒泡和快速)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 关于查找(二分查找)和排序(冒泡和快速)

查找:二分查找


1.解析:


目前我的理解,二分查找是运用在一组有序的数据当中,且时间复杂度为O(loggif.gif);为什么是loggif.gif?【对于时间复杂度还不明白的可以看我的博客(一道经典的C语言面试题)】;因为它每次都能排除一半的数据!!!最终就是n   n/2   n/4 ..... 1是一个以2为底等比数列,最终就是 O(loggif.gif)

2.注意:


在我们动手写之前,我们要想明白要创建的变量:


1.创建一个数组(暂定为arr)用来存取数据


2.创建一个计算数组大小的变量(暂定sz)


3.创建一个变量代表要查找的数(暂定k)


4.创建一个可以代表中间数据下标的数据(暂定为mid);既然要求中间数据的下标,肯定要知道最左边(暂定为left)和最右边(暂定为right)的下标;因为mid = (left+right) / 2 啊!!!


当我们理清楚要创建的变量,代码的思路肯定就已经在我们心里了,下面看具体代码是实现


3.具体代码实现:


e3ce92816418447189beb8e35e2fb064.png


4.代码解析:

 

让我们来详细解析一下这段代码:

1.我是封装成函数的形式,那么我们要想一下,我们要传什么实参呢?首先数组(arr)肯定要传过去的;大小(sz),要传吗?等数组传过去过后,在函数里求sz可以吗?答案是否定的,我们传过去的数组实际上是首元素的的地址,如果用传过去的数组,在封装的函数里在计算sz的大小,结果并不是我们想要的结果;所以我们要记住一点:对于数组要想知道数组的大小,必须现在主函数里计算好,在传参传给函数里,不能在函数里直接求;还有就是要c传过去要查找的数k


   2.对于循环条件,肯定是left<right;左边数据的下标肯定不能超过右边数据的下标;但是对于while(left<right)这个判断条件,很多人都不太明白要不要带等号呢?如果你分不清,可以试试下面这种方式:


====》如果left = 0 , right = sz======>right实际上是只能取到sz-1;所以写成while(left<right)


====》如果left = 0 , right = sz-1======>right实际上是就能取到sz-1;所以写成while(left<=right)


3. 如果arr[mid]>k;说明数据要查找的数据在mid的左边,就把right=mid-1;重新再求mid

 

如果arr[mid]<k;说明数据要查找的数据在mid的右边,就把left=mid+1;重新再求mid


 

就这样一直循环下去,最终找到要查找的数据,break跳出循环,返回它的下标


排序:冒泡排序和快速排序

冒泡排序

1.解析:


对于冒泡排序我们要弄清楚一个事,要排几趟?每趟要交换几个元素?===》升序排

 

1. 对于n个元素,我们最多要排几趟才可以使它有序呢?当然是n-1趟就可以了!!!

 

2. 那么每趟交换几个元素呢?比如有6个元素吧,第一趟交换5个,既可以确定一个元素,那么第二趟只需交换4个就可以确定第二个元素......我们不难发现规律,交换的次数,是随着要排的趟数增加而递减的;很容易想明白吧,随着趟数的增加,确定的元素越多,最终交换的次数就会变少;假如排的趟数是i;那么每趟要交换的次数就是n-1-i

 

3. 我们就按照升序排,用i来控制趟数=========》n-1趟

                                   

用j来控制交换次数======》n-1-i交换次数


遇到前面的值比后面大,就进行交换


2.下面看具体代码:

db0ba967fdc440a0b4bb1ab464c542cf.png


我们封装一个函数来写,当然你也可以不封装成函数来写,函数传参怎么办呢?传那些变量,首先数组arr肯定要传过去的,然后就是数组的大小sz要传过去,就可以了。冒泡排序可能是最好理解的排序方法。但是冒泡排序有一个弊端,只能传整型数据。


快速排序:


1.解析:


对于快速排序我们可以用库函数qsort,可以用MSDN来查看一下qsort函数的参数:


void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );


我来解释一下:qsort函数可以传各种的数据类型,总共需要四个参数:


qsort(数组名, 数组大小 , 宽度 ,函数)===》比如:对于一个整型数组arr[10],有10个元素,一个整型占4个字节,宽度就是4 ====》qsort(arr ,10 , 4,qsort_bubble )其中qsort_bubble函数是我们自己定义的,它的使用包括返回类型是根据我们的需要设置的;比如:


a159351b58134d3d98d0c2eb8438e390.png


因为是整型数据,所以返回类型是int ;e1和e2加上const修饰,表示不能改变,毕竟我们只是排序,并不改变它的值;因为不知道接收过来的是什么类型的参数,所以类型定义为void,使用时根据类型自己强制类型转化。


2.下面看具体代码:

99f625622bd4481fb08ff031beffcc12.png


3.注意:


我们需要注意两点:


1. 如果是e1-e2那么就是升序,如果e2-e1就是降序啦;它是根据返回的值是>0 =0 <0来判断大小的。


2. 对于整型数据,我们可以直接强制类型转换后,相减看与0的关系;


那么对于字符型呢?就需要strcmp函数来比较字符串啦,同样也是根据返回值>0 =0 <0来排序。


qsort函数的调用需要引头文件<stdlib.h>


4.总结:

 

以上就是我所知道的查找和排序算法;等我学完数据结构,再来补一期完整版的查找和排序,一起加油吧!!!

相关文章
|
6月前
|
搜索推荐 算法
三大排序:冒泡、选择、插入
三大排序:冒泡、选择、插入
39 2
|
1月前
|
Java 索引
|
5月前
|
搜索推荐
排序(冒泡、选择、插入、希尔、归并、快速)
排序(冒泡、选择、插入、希尔、归并、快速)
|
6月前
|
算法 Java C++
实现一个二分搜索算法,搜索指定元素在已排序数组中的位置。(递归或者非递归实现)
实现一个二分搜索算法,搜索指定元素在已排序数组中的位置。(递归或者非递归实现)
43 0
|
6月前
|
人工智能
数组排序,查找
数组排序,查找
|
6月前
|
算法 程序员 索引
【算法训练-二分查找 一】【基本二分】二分查找、在排序数组中查找元素的第一个和最后一个位置
【算法训练-二分查找 一】【基本二分】二分查找、在排序数组中查找元素的第一个和最后一个位置
56 0
27. 移除元素 26. 删除有序数组中的重复项 88. 合并两个有序数组(双指针遍历)上
27. 移除元素 26. 删除有序数组中的重复项 88. 合并两个有序数组(双指针遍历)上
61 1
|
算法
算法排序选择冒泡
算法排序选择冒泡
54 0