开发人员必知8大排序3大查找
查找排序

解:① 先设定3个辅助标志: low,high,mid, 显然有:mid= (low+high)/2 ② 运算步骤:
(1) low =1,high =11 ,故mid =6 ,待查范围是 [1,11]; (2) 若 S[mid] < key,说明 key[ mid+1,high] , 则令:low =mid+1;重算 mid= (low+high)/2;. (3) 若 S[mid] > key,说明key[low ,mid-1], 则令:high =mid–1;重算 mid ; (4)若 S[ mid ] = key,说明查找成功,元素序号=mid; 结束条件: (1)查找成功 : S[mid] = key (2)查找不成功 : high<low (意即区间长度小于0)
while(low<=high)
{ mid=(low+high)/2; if(ST[mid].key= = key) return (mid); /*查找成功*/
else if( key< ST[mid].key) high=mid-1; /*在前半区间继续查找*/ else } return (0); /*查找不成功*/
4 5 6 7
0
1
2
90
10
(c)
20
40
K=90
80
30
60
Hale Waihona Puke 25(return i=0 )
6
讨论:怎样衡量查找效率?
——用平均查找长度(ASL)衡量。
如何计算ASL?
Java常用排序总结

Java排序总结日常操作中常见的排序方法有:冒泡排序、快速排序、选择排序、插入排序、希尔排序,甚至还有基数排序、鸡尾酒排序、桶排序、鸽巢排序、归并排序等。
冒泡排序是一种简单的排序算法。
它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。
走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。
这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。
代码/*** 冒泡法排序<br/>* <li>比较相邻的元素。
如果第一个比第二个大,就交换他们两个。
</li>* <li>对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。
在这一点,最后的元素应该会是最大的数。
</li>* <li>针对所有的元素重复以上的步骤,除了最后一个。
</li>* <li>持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
</li>** @param numbers* 需要排序的整型数组*/public static void bubbleSort(int[] numbers) {int temp; // 记录临时中间值int size = numbers.length; // 数组大小for(int i = 0; i < size - 1; i++) {for(int j = i + 1; j < size; j++) {if(numbers[i] < numbers[j]) { // 交换两数的位置temp = numbers[i];numbers[i] = numbers[j];numbers[j] = temp;}}}}快速排序使用分治法策略来把一个序列分为两个子序列。
代码/*** 快速排序<br/>* <ul>* <li>从数列中挑出一个元素,称为“基准”</li>* <li>重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。
Java常见的七种查找算法

Java常见的七种查找算法1. 基本查找也叫做顺序查找,说明:顺序查找适合于存储结构为数组或者链表。
基本思想:顺序查找也称为线形查找,属于无序查找算法。
从数据结构线的一端开始,顺序扫描,依次将遍历到的结点与要查找的值相比较,若相等则表示查找成功;若遍历结束仍没有找到相同的,表示查找失败。
示例代码:public class A01_BasicSearchDemo1 {public static void main(String[] args){//基本查找/顺序查找//核心://从0索引开始挨个往后查找//需求:定义一个方法利用基本查找,查询某个元素是否存在//数据如下:{131, 127, 147, 81, 103, 23, 7, 79}int[] arr ={131,127,147,81,103,23,7,79};int number =82;System.out.println(basicSearch(arr, number));}//参数://一:数组//二:要查找的元素//返回值://元素是否存在public static boolean basicSearch(int[] arr,int number){//利用基本查找来查找number在数组中是否存在for(int i =0; i < arr.length; i++){if(arr[i]== number){return true;}}return false;}}2. 二分查找也叫做折半查找,说明:元素必须是有序的,从小到大,或者从大到小都是可以的。
如果是无序的,也可以先进行排序。
但是排序之后,会改变原有数据的顺序,查找出来元素位置跟原来的元素可能是不一样的,所以排序之后再查找只能判断当前数据是否在容器当中,返回的索引无实际的意义。
基本思想:也称为是折半查找,属于有序查找算法。
用给定值先与中间结点比较。
比较完之后有三种情况:•相等说明找到了•要查找的数据比中间节点小说明要查找的数字在中间节点左边•要查找的数据比中间节点大说明要查找的数字在中间节点右边代码示例:package com.itheima.search;public class A02_BinarySearchDemo1 {public static void main(String[] args){//二分查找/折半查找//核心://每次排除一半的查找范围//需求:定义一个方法利用二分查找,查询某个元素在数组中的索引//数据如下:{7, 23, 79, 81, 103, 127, 131, 147}int[] arr ={7,23,79,81,103,127,131,147};System.out.println(binarySearch(arr,150));}public static int binarySearch(int[] arr,int number){//1.定义两个变量记录要查找的范围int min =0;int max = arr.length-1;//2.利用循环不断的去找要查找的数据while(true){if(min > max){return-1;}//3.找到min和max的中间位置int mid =(min + max)/2;//4.拿着mid指向的元素跟要查找的元素进行比较if(arr[mid]> number){//4.1 number在mid的左边//min不变,max = mid - 1;max = mid -1;}else if(arr[mid]< number){//4.2 number在mid的右边//max不变,min = mid + 1;min = mid +1;}else{//4.3 number跟mid指向的元素一样//找到了return mid;}}}}3. 插值查找在介绍插值查找之前,先考虑一个问题:为什么二分查找算法一定要是折半,而不是折四分之一或者折更多呢?其实就是因为方便,简单,但是如果我能在二分查找的基础上,让中间的mid点,尽可能靠近想要查找的元素,那不就能提高查找的效率了吗?二分查找中查找点计算如下:mid=(low+high)/2, 即mid=low+1/2*(high-low);我们可以将查找的点改进为如下:mid=low+(key-a[low])/(a[high]-a[low])*(high-low),这样,让mid值的变化更靠近关键字key,这样也就间接地减少了比较次数。
顺序查找直接查找折半查找算法

顺序查找直接查找折半查找算法一、顺序查找算法顺序查找也被称为线性查找,是一种简单直观的算法。
其基本原理是逐个遍历数据集中的元素,直到找到目标值为止。
算法步骤如下:1.从数据集的第一个元素开始顺序遍历。
2.如果当前元素与目标值相同,返回元素的索引。
3.如果遍历到数据集的最后一个元素仍未找到目标值,返回失败。
顺序查找算法的时间复杂度为O(n),其中n为数据集的大小。
由于需要遍历整个数据集,这种算法适用于小型数据集。
二、直接查找算法直接查找算法也被称为线性查找优化算法,其思想是在遍历数据集时,通过跳跃一定步长快速确定目标值所在的范围,然后在该范围内进行顺序查找。
算法步骤如下:1.设定步长为k。
2.从数据集的第一个元素开始,每次跳跃k个元素。
3.如果当前元素大于目标值,将步长减半并继续跳跃,直到找到目标值或步长变为1为止。
4.在跳跃范围内进行顺序查找,找到目标值则返回索引,否则返回失败。
直接查找算法的时间复杂度为O(n/k),其中n为数据集的大小,k为步长。
通过调整步长,可以在时间和空间之间取得平衡。
折半查找算法是一种效率较高的算法,也被称为二分查找。
其基本原理是将数据集分为两半,通过比较目标值与中间元素的大小关系来确定目标值所在的范围,然后在该范围内进行递归查找。
算法步骤如下:1.将数据集按升序或降序排列。
2.初始化左右指针,分别指向数据集的第一个和最后一个元素。
3.计算中间元素的索引。
4.如果中间元素等于目标值,则返回索引。
5.如果中间元素大于目标值,则更新右指针为中间元素的前一个元素,重复步骤36.如果中间元素小于目标值,则更新左指针为中间元素的后一个元素,重复步骤37.当左指针大于右指针时,返回失败。
折半查找算法的时间复杂度为O(logn),其中n为数据集的大小。
由于每次都将数据集分为两半,因此效率较高。
但是该算法要求数据集必须有序。
综上所述,顺序查找、直接查找和折半查找算法都是常用的算法,适用于不同规模和有序性的数据集。
程序员必须知道的8大排序和3大查找

程序员必须知道的8大排序和3大查找现在我们分析一下8种排序算法的稳定性。
(请网友结合前面的排序基本思想来理解排序的稳定性(8种排序的基本思想已经在前面说过,这里不再赘述)不然可能有些模糊)(1)直接插入排序:一般插入排序,比较是从有序序列的最后一个元素开始,如果比它大则直接插入在其后面,否则一直往前比。
如果找到一个和插入元素相等的,那么就插入到这个相等元素的后面。
插入排序是稳定的。
(2)希尔排序:希尔排序是按照不同步长对元素进行插入排序,一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,稳定性就会被破坏,所以希尔排序不稳定。
(3)简单选择排序:在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。
光说可能有点模糊,来看个小实例:858410,第一遍扫描,第1个元素8会和4交换,那么原序列中2个8的相对前后顺序和原序列不一致了,所以选择排序不稳定。
(4)堆排序:堆排序的过程是从第n/2开始和其子节点共3个值选择最大(大顶堆)或者最小(小顶堆),这3个元素之间的选择当然不会破坏稳定性。
但当为n /2-1, n/2-2, ...这些父节点选择元素时,有可能第n/2个父节点交换把后面一个元素交换过去了,而第n/2-1个父节点把后面一个相同的元素没有交换,所以堆排序并不稳定。
(5)冒泡排序:由前面的内容可知,冒泡排序是相邻的两个元素比较,交换也发生在这两个元素之间,如果两个元素相等,不用交换。
所以冒泡排序稳定。
(6)快速排序:在中枢元素和序列中一个元素交换的时候,很有可能把前面的元素的稳定性打乱。
还是看一个小实例:6 4 4 5 4 7 8 9,第一趟排序,中枢元素6和第三个4交换就会把元素4的原序列破坏,所以快速排序不稳定。
(7)归并排序:在分解的子列中,有1个或2个元素时,1个元素不会交换,2个元素如果大小相等也不会交换。
搜索算法二分查找深度优先搜索和广度优先搜索

搜索算法二分查找深度优先搜索和广度优先搜索搜索算法:二分查找、深度优先搜索和广度优先搜索引言:搜索算法是计算机科学中重要的算法之一,它用来在给定的数据集中查找特定的元素或解决某个问题。
本文将重点介绍三种常用的搜索算法:二分查找、深度优先搜索和广度优先搜索。
通过对这些算法的介绍,读者将了解它们的原理、特点以及应用场景,从而更好地理解搜索算法的工作原理及其在实际开发中的应用。
一、二分查找二分查找(Binary Search)是一种高效的查找算法,它适用于有序数组。
算法的基本思路是从数组的中间元素开始比较,如果要查找的元素小于中间元素,则去数组的左半部分继续查找,否则去数组的右半部分继续查找。
通过不断缩小查找范围,最终可以找到目标元素或确定目标元素不存在于数组中。
二、深度优先搜索深度优先搜索(Depth First Search,DFS)是一种用于遍历或搜索树或图的算法。
它从起始节点开始,尽可能深地访问每个节点的未访问邻居,直到遇到无法继续前进的节点,然后回溯到上一个节点,继续深入访问其他未访问的节点,直到所有节点都被访问完毕。
DFS通常采用递归或栈的方式实现。
三、广度优先搜索广度优先搜索(Breadth First Search,BFS)也是一种用于遍历或搜索树或图的算法。
与深度优先搜索不同,BFS先访问起始节点的所有邻居节点,然后再访问邻居节点的邻居节点,依次向外拓展。
BFS通常采用队列的方式实现。
四、二分查找的应用场景1. 在有序数组中查找指定元素。
由于二分查找的时间复杂度为O(logN),因此它在处理大规模数据集时非常高效。
例如,在一个包含百万个元素的数组中,通过二分查找可以迅速确定某个元素是否存在。
五、深度优先搜索的应用场景1. 图的遍历。
深度优先搜索可以用来遍历图的所有节点,查找特定节点或判断两个节点之间是否存在路径。
例如,可以使用DFS查找一个社交网络中与某个人关系最近的所有人。
六、广度优先搜索的应用场景1. 最短路径问题。
程序员必知8大排序3大查找(三)

程序员必知8大排序3大查找(三)三种查找算法:顺序查找,二分法查找(折半查找),分块查找,散列表(以后谈)一、顺序查找的基本思想:从表的一端开始,顺序扫描表,依次将扫描到的结点关键字和给定值(假定为a)相比较,若当前结点关键字与a相等,则查找成功;若扫描结束后,仍未找到关键字等于a的结点,则查找失败。
说白了就是,从头到尾,一个一个地比,找着相同的就成功,找不到就失败。
很明显的缺点就是查找效率低。
适用于线性表的顺序存储结构和链式存储结构。
计算平均查找长度。
例如上表,查找1,需要1次,查找2需要2次,依次往下推,可知查找16需要16次,可以看出,我们只要将这些查找次数求和(我们初中学的,上底加下底乘以高除以2),然后除以结点数,即为平均查找长度。
设n=节点数平均查找长度=(n+1)/2二、二分法查找(折半查找)的基本思想:前提:(1)确定该区间的中点位置:mid=(low+high)/2min代表区间中间的结点的位置,low代表区间最左结点位置,high代表区间最右结点位置(2)将待查a值与结点mid的关键字(下面用R[mid].key)比较,若相等,则查找成功,否则确定新的查找区间:如果R[mid].key>a,则由表的有序性可知,R[mid].key右侧的值都大于a,所以等于a的关键字如果存在,必然在R[mid].key左边的表中。
这时high=mid-1如果R[mid].key<a,则等于a的关键字如果存在,必然在R[mid].key右边的表中。
这时low=mid如果R[mid].key=a,则查找成功。
(3)下一次查找针对新的查找区间,重复步骤(1)和(2)(4)在查找过程中,low逐步增加,high逐步减少,如果high<low,则查找失败。
平均查找长度=Log2(n+1)-1注:虽然二分法查找的效率高,但是要将表按关键字排序。
而排序本身是一种很费时的运算,所以二分法比较适用于顺序存储结构。
如何在Java中进行数据的排序和搜索

如何在Java中进行数据的排序和搜索在Java中对数据进行排序和搜索是非常常见的操作。
排序和搜索是数据处理中最基本的功能之一,在Java中有多种方式来完成排序和搜索的功能。
本文将从数组、集合和搜索算法三个方面来介绍在Java 中进行数据的排序和搜索。
一、数组的排序与搜索在Java中,对数组进行排序和搜索是非常常见的操作。
Java提供了两种对数组进行排序的方法:Arrays.sort()方法和Collections.sort()方法。
Arrays.sort()方法可以对基本类型数组和对象数组进行排序,而Collections.sort()方法只能对对象数组进行排序。
这两种方法都是使用快速排序算法来对数组进行排序的。
1. Arrays.sort()方法Arrays.sort()方法是针对基本类型数组和对象数组进行排序的。
对于基本类型数组,Arrays.sort()方法会调用Arrays类中相应的排序方法。
对于对象数组,Arrays.sort()方法会根据对象的自然顺序进行排序。
示例代码如下:```javaint[] arr = {5, 3, 8, 2, 1};Arrays.sort(arr);System.out.println("Sorted array: " +Arrays.toString(arr)); //输出:[1, 2, 3, 5, 8]```2. Collections.sort()方法Collections.sort()方法是针对对象数组进行排序的。
这个方法可以对实现了Comparable接口的对象进行排序,也可以对实现了Comparator接口的对象进行排序。
示例代码如下:```javaList<Integer> list = new ArrayList<>();list.add(5);list.add(3);list.add(8);list.add(2);list.add(1);Collections.sort(list);System.out.println("Sorted list: " + list); //输出:[1, 2, 3, 5, 8]```3.二分查找在Java中,可以使用Arrays.binarySearch()方法来进行二分查找。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
开发人员必知8大排序3大查找每天都在叫嚣自己会什么技术,什么框架,可否意识到你每天都在被这些新名词、新技术所迷惑,.NET、XML等等技术固然诱人,可是如果自己的基础不扎实,就像是在云里雾里行走一样,只能看到眼前,不能看到更远的地方。
这些新鲜的技术掩盖了许多底层的原理,要想真正的学习技术还是走下云端,扎扎实实的把基础知识学好,有了这些基础,要掌握那些新技术也就很容易了。
要编写出优秀的代码同样要扎实的基础,如果排序和查找算法学的不好,怎么对程序的性能进行优化?废话不多说,本文要介绍的这些排序算法就是基础中的基础,程序员必知!1、直接插入排序(1)基本思想:在要排序的一组数中,假设前面(n-1) [n>=2] 个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。
如此反复循环,直到全部排好顺序。
(2)实例2、希尔排序(也称最小增量排序)(1)基本思想:算法先将要排序的一组数按某个增量d(n/2,n为要排序数的个数)分成若干组,每组中记录的下标相差d.对每组中全部元素进行直接插入排序,然后再用一个较小的增量(d/2)对它进行分组,在每组中再进行直接插入排序。
当增量减到1时,进行直接插入排序后,排序完成。
(2)实例:3、简单选择排序(1)基本思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换;然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止。
(2)实例:4、堆排序(1)基本思想:堆排序是一种树形选择排序,是对直接选择排序的有效改进。
堆的定义如下:具有n个元素的序列(h1,h2,...,hn),当且仅当满足(hi>=h2i,hi>=2i+1)或(hi<=h2i,hi<=2i+1)(i=1,2,...,n/2)时称之为堆。
在这里只讨论满足前者条件的堆。
由堆的定义可以看出,堆顶元素(即第一个元素)必为最大项(大顶堆)。
完全二叉树可以很直观地表示堆的结构。
堆顶为根,其它为左子树、右子树。
初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的存储序,使之成为一个堆,这时堆的根节点的数最大。
然后将根节点与堆的最后一个节点交换。
然后对前面(n-1)个数重新调整使之成为堆。
依此类推,直到只有两个节点的堆,并对它们作交换,最后得到有n个节点的有序序列。
从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。
所以堆排序有两个函数组成。
一是建堆的渗透函数,二是反复调用渗透函数实现排序的函数。
(2)实例:初始序列:46,79,56,38,40,84建堆:交换,从堆中踢出最大数剩余结点再建堆,再交换踢出最大数依次类推:最后堆中剩余的最后两个结点交换,踢出一个,排序完成。
5、冒泡排序(1)基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。
即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
(2)实例:6、快速排序(1)基本思想:选择一个基准元素,通常选择第一个元素或者最后一个元素,通过一趟扫描,将待排序列分成两部分,一部分比基准元素小,一部分大于等于基准元素,此时基准元素在其排好序后的正确位置,然后再用同样的方法递归地排序划分的两部分。
(2)实例:上图中将待排序列分成两部分,一部分比基准元素小,一部分大于基准元素,然后对这两部分重复上图的求解过程。
(这只是快速排序的一种实现方式,个人认为比较容易理解)7、归并排序(1)基本排序:归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。
然后再把有序子序列合并为整体有序序列。
(2)实例:8、基数排序(1)基本思想:将所有待比较数值(正整数)统一为同样的数位长度,数位较短的数前面补零。
然后,从最低位开始,依次进行一次排序。
这样从最低位排序一直到最高位排序完成以后,数列就变成一个有序序列。
(2)实例:稳定性说明:排序前,2(或者更多)个相等的数在序列的前后位置顺序和排序后它们在序列中的前后位置顺序一样。
实例:待排序数列:5,4,8,6,1,8,7,9排序结果:1,4,5,6,7,8,8,9稳定:1,4,5,6,7,8,8,9不稳定:1,4,5,6,7,8,8,9说明:对比红色的8和紫色的8,看他们排序前后的位置。
排序前,红8在紫8前面,如果排序后红8仍然在紫8前面,则排序算法稳定,否则不稳定。
现在我们分析一下8种排序算法的稳定性。
(1)直接插入排序:一般插入排序,比较是从有序序列的最后一个元素开始,如果比它大则直接插入在其后面,否则一直往前比。
如果找到一个和插入元素相等的,那么就插入到这个相等元素的后面。
插入排序是稳定的。
(2)希尔排序:希尔排序是按照不同步长对元素进行插入排序,一次插入排序是稳定的,不会改变相同元素的相对顺序,但在不同的插入排序过程中,相同的元素可能在各自的插入排序中移动,稳定性就会被破坏,所以希尔排序不稳定。
(3)简单选择排序:在一趟选择,如果当前元素比一个元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了。
光说可能有点模糊,来看个小实例:858410,第一遍扫描,第1个元素8会和4交换,那么原序列中2个8的相对前后顺序和原序列不一致了,所以选择排序不稳定。
(4)堆排序:堆排序的过程是从第n/2开始和其子节点共3个值选择最大(大顶堆)或者最小(小顶堆),这3个元素之间的选择当然不会破坏稳定性。
但当为n/2-1, n/2-2, ...这些父节点选择元素时,有可能第n/2个父节点交换把后面一个元素交换过去了,而第n/2-1个父节点把后面一个相同的元素没有交换,所以堆排序并不稳定。
(5)冒泡排序:由前面的内容可知,冒泡排序是相邻的两个元素比较,交换也发生在这两个元素之间,如果两个元素相等,不用交换。
所以冒泡排序稳定。
(6)快速排序:在中枢元素和序列中一个元素交换的时候,很有可能把前面的元素的稳定性打乱。
还是看一个小实例:6 4 4 5 4 7 8 9,第一趟排序,中枢元素6和第三个4交换就会把元素4的原序列破坏,所以快速排序不稳定。
(7)归并排序:在分解的子列中,有1个或2个元素时,1个元素不会交换,2个元素如果大小相等也不会交换。
在序列合并的过程中,如果两个当前元素相等时,我们把处在前面的序列的元素保存在结果序列的前面,所以,归并排序也是稳定的。
(8)基数排序:是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。
有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序,最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。
基数排序基于分别排序,分别收集,所以是稳定的。
8种排序的分类,稳定性,时间复杂度和空间复杂度总结:三种查找算法:顺序查找,二分法查找(折半查找),分块查找,散列表(以后谈)一、顺序查找的基本思想:从表的一端开始,顺序扫描表,依次将扫描到的结点关键字和给定值(假定为a)相比较,若当前结点关键字与a相等,则查找成功;若扫描结束后,仍未找到关键字等于a的结点,则查找失败。
说白了就是,从头到尾,一个一个地比,找着相同的就成功,找不到就失败。
很明显的缺点就是查找效率低。
适用于线性表的顺序存储结构和链式存储结构。
计算平均查找长度。
例如上表,查找1,需要1次,查找2需要2次,依次往下推,可知查找16需要16次,可以看出,我们只要将这些查找次数求和(我们初中学的,上底加下底乘以高除以2),然后除以结点数,即为平均查找长度。
设n=节点数平均查找长度=(n+1)/2二、二分法查找(折半查找)的基本思想:前提:(1)确定该区间的中点位置:mid=(low+high)/2min代表区间中间的结点的位置,low代表区间最左结点位置,high代表区间最右结点位置(2)将待查a值与结点mid的关键字(下面用R[mid].key)比较,若相等,则查找成功,否则确定新的查找区间:如果R[mid].key>a,则由表的有序性可知,R[mid].key右侧的值都大于a,所以等于a的关键字如果存在,必然在R[mid].key左边的表中。
这时high=mid-1如果R[mid].key<a,则等于a的关键字如果存在,必然在R[mid].key右边的表中。
这时low=mid如果R[mid].key=a,则查找成功。
(3)下一次查找针对新的查找区间,重复步骤(1)和(2)(4)在查找过程中,low逐步增加,high逐步减少,如果high<low,则查找失败。
平均查找长度=Log2(n+1)-1注:虽然二分法查找的效率高,但是要将表按关键字排序。
而排序本身是一种很费时的运算,所以二分法比较适用于顺序存储结构。
为保持表的有序性,在顺序结构中插入和删除都必须移动大量的结点。
因此,二分查找特别适用于那种一经建立就很少改动而又经常需要查找的线性表。
三、分块查找的基本思想:二分查找表使分块有序的线性表和索引表(抽取各块中的最大关键字及其起始位置构成索引表)组成,由于表是分块有序的,所以索引表是一个递增有序表,因此采用顺序或二分查找索引表,以确定待查结点在哪一块,由于块内无序,只能用顺序查找。
设表共n个结点,分b块,s=n/b(分块查找索引表)平均查找长度=Log2(n/s+1)+s/2(顺序查找索引表)平均查找长度=(S2+2S+n)/(2S)注:分块查找的优点是在表中插入或删除一个记录时,只要找到该记录所属块,就在该块中进行插入或删除运算(因块内无序,所以不需要大量移动记录)。
它主要代价是增加一个辅助数组的存储控件和将初始表分块排序的运算。
它的性能介于顺序查找和二分查找之间。
四、最近比较忙,后续找个时间还会谈谈散列表(哈希表)技术,希望大家关注!散列表查找技术不同于顺序查找、二分查找、分块查找。
它不以关键字的比较为基本操作,采用直接寻址技术。
在理想情况下,无须任何比较就可以找到待查关键字,查找的期望时间为O(1)。
文章整理:疯狂的IT人()。