我们讲了各种数据 结构之后,比如讲了线性表了,讲了栈和队列,讲了树和二叉树,讲了图之后呢,我们最后还有两个专题,一个叫查找,一个叫排序,我们先看看查找,查找包括哪些内容啊,第一个线性表的查找,数组或者链表的查找,这是一个,还有一个呢,树的查找,涉及到的一个概念二叉查找树,还有一个是哈希表的查找,哈下表的查找开始我们讲集合的时候其实已经接触过了,最后我们再讲一下Java里面有哪些查找树和哈希表,这就是我们查找树的内容,线性表的查找我们以数组为例来进行讲解,线性查找有顺序查找和折半查找,跟底层采用什么存储结构是没有关系的,只不过我们目前是采用数组来实现,大家也可以采用相关的链表,现在我们先来看这一部分1. 顺序查找:比如我们这里面定义了一个数组,这个数组里面存了分数,我要在这里面找一个分数,找100分,在成绩中查找分数是100的第一个分数,怎么办,有没有顺序,他是不是大小排列的,不是大小排列的,他不是大小排列的,所以这个时候你只能干什么,只能逐个来比较,最终找到第一个100的,这个效率是高还是低,这个效率是低的,但是你没有办法,你只能这么来,要是学生呢,就复杂了呗,数组里面放的就不是int了,成了Student了,那也类似吗,但是还有一种情况,提高效率的话,这个数组里面放的不能是分数了,他现在是不是有序的,有序的我们就能改变一种思路,你没有必要一个一个找了,可以折半查找,我要找8份,你怎么找8分,我先找最中间的那个,这个6居然比8小,只要这一半,可以再折半,每次砍掉长度的½,这个效率是非常高的,但是他有前提条件,有什么条件,它是有序的,还有一点呢,那对这个折半查找,他要求采用数组,要是你不采用数组的话,他底层链表也是不连续的,这样一来效率也不怎么高,这是我们所说的我们再来看看折半查找,折半查找也叫二分查找,使用这种查找的话需要满足两个条件1. 第一个要求是顺序存储结构2. 第二个必须是有序的,比如这个数组从5一直到52,是不是一直都是有序的,这种情况下我们要是再按照顺序查找的话我们就会发现他的缺点,效率比较低,那么我们怎么来办,折半查找,我们来看一下,我们要在这里找21,该怎么找,就是这么来找,我们上面写的0到10是什么意思,是索引,在往下边是分数,是两个指针,也就是两个整形的变量,low首先指向第一个,是0吧,high指向最后,是10,(0+10)/2=5,整除就可以了,5,mid是什么意思,中间,索引就是5,你找的是谁,我们找的就是21,拿着21跟56比,这一半就全部排出了,肯定不在有一半了,一共有一亿个树,一下子就消灭了5000万,5000万不用考虑了,哪还有5000万呢,在分一次就是2500万,是不是又没有了,我们讲过2倍2倍的增,现在我们是½的减,这个速度是非常快的,那告诉我下一步该怎么办了,这个Low变不变,;low还是0,low是不变的,mid是计算出来的,下次改的是high,起点还是low,终点是high,它的索引是4,怎么成了4了,之前那个幂的是5,5前面这个一个呗,找他就可以了,high=mid-1=4,一个是0,一个是4,头0尾4,取中间值,(0+4)/2=2,mid等于2,拿着这个21和19比,这个肯定不会的,就排除了那下一步告诉我指针该怎么变,low和high该怎么变,high要不要变,high不变,范围又是这一块了,high不变还是4,low应该是几,是mid+1,是不是3,(3+4)/2你可别来个3.5,没有3.5,3,mid指向3,指向3了,找到了,他这个时间复杂度是多少啊就是我们之前说的log2 n,每次他都会减少二分之一,这个log2 n是什么含义,这个n和log2 n有什么差别,如果n是10亿次,如果你的级别是n,你就得找10亿次,但是如果你是log2 n,n给他10亿的话,就是2的30次方就是10亿,30次就够了,20次和10亿次天差地别,这你知道这个效率有多高,明确一下,这个效率是特别高的,这是我们讲的一个内容,我们举了这个例子好在什么程度,我们的high动了一次,high要变成mid-1,下次再比的话low又要变一下,low要变成mid+1,这里面就是我们要写的一个算法,你告诉我他什么时候可以结束啊,什么时候开始结束,这个值等于21的时候就结束了,是那样吗那你给我找个85,找个85的,这里面没有85,一个80,一个88,那怎么办,那就是按照刚才的规则一直在动,动来动去,就会出现一个情况,什么情况,这个图已经很明白了,low,high,取中间,low等于9,mid等于9,到这儿还没有结束呢,结果拿着88和85相比,他是不是在这一边呢,结果变成low等于9,mid现在也是9,他在这边的就是high了,high等于mid-1他的前一个,high变成8了,你看怎么了,low比high还大,说明没有找不到,所以找到没找到,内容都在这儿,这是我们讲的递归,明确折半查找的思路,第二个知道他的时间复杂度,log2 n级别的,这个效率特别高,下边我们就来写这个代码了
package com.learn.search;/*** 查找功能:在分数中查询指定分数的索引,在第几个位置* * 关于这个顺序的查找非常的简单,* 那我们分析一下这个时间复杂度是多少,* 他的时间复杂度写一个大欧,* T(n) = O(n)* 如果这个数组的长度是n个的话,* 那平均下来会找一半,去掉系数是O(n)* 所以这个数如果几百万的话,查找次数还是挺多的* 效率还是挺低的* 再写一个S(n),空间复杂度是多少* 不需要用到什么变量,只要一个index,一个i* 别的他不需要,所以这个不需要占用更多的空间* S(n) = O(1)* 效率低下* 这个讲数组操作的时候都应该已经讲过* 非常简单* 逐个比较,如果找到,返回数据或者索引* 找不到就返回null或者-1* 可以是顺序表,也可以是链表* 在各个节点查找概率相同的情况下,* 默认的查询长度是一半,* 所以时间复杂度是O(n)* 这个非常的简单* @author Leon.Sun**/
public class TestSearch1 {public static void main(String[] args) {/*** 第一步给定分数数组* * 给定数组*/int [] scoreArr = {89,45,78,45,100,98,86,100,65};/*** 给定要查找的分数* * 分数就是他了* * 找个65*/// int score = 100;/*** 一共9个数,索引是8*/// int score = 65;/*** 找个650,是-1*/int score = 65;/*** 完成查找* * 最终我们会得到一个index* * 默认的index是-1*/
//      int index = -1;/*** 最难的这一步怎么办* 能怎么办,来一个for循环* * 但是对于查找我们要提取一个方法*/
//      for(int i=0;i<scoreArr.length;i++) {
//          /**
//           * 逐个判断
//           */
//          if(scoreArr[i]==score) {
//              /**
//               * 那怎么办,找到了没有
//               * 能return 吗,return那main方法就结束了
//               * 这不能用return,index就等于i
//               * 找到就是i
//               */
//              index = i;
//              /**
//               * 再加个操作
//               * 找到100后面就不比了,
//               *
//               * break一下也就不循环了
//               */
//              break;
//          }
//      }/*** 输出结果* * 输出一下,怎么输出啊* 那就看index等于几了呗* 如果index等于-1,那就输出一下不存在* * 一共是分4步,我们都一斤完成3步了* */
//      if(index==-1) {
//          System.out.println("该分数不存在");
//      }else {
//          /**
//           * 100的索引是4,是4吗
//           *
//           */
//          System.out.println(score + "索引是:" + index);
//      }/*** 怎么查找,刚才我们要查找的话,你不仅知道你要干什么* 你还要知道怎么来完成,你们知道这个思路吗,* 现在不用了,你只要知道你想干什么就行了* 我想查找,直接调用一个search,* 这个他里面是怎么实现的,我才不管呢* * 这边传谁,传一个scoreArr,再传一个score* 有没有问题,没有了,*/int index = search(scoreArr,score);}/*** 返回值是什么,是int,索引吗* 需要传一个什么内容,* * 这里面我们应该传一个数组,还要穿一个score* * 方法提取,这个方法就可以重用* * 我们这里改一下不叫scoreArr,难道只能改分数吗* 不仅可以找分数,还可以找其他的*/public static int search(int[] arr,int key) {int index = -1;for(int i=0;i<arr.length;i++) {if(arr[i]==key) {index = i;break;}}if(index==-1) {System.out.println("该分数不存在");}else {System.out.println(key + "索引是:" + index);}/*** 返回这个索引就行了*/return index;}}
package com.learn.search;/*** 告诉我他又什么前提,* 前提是什么,第一个顺序结构,第二个按照关键字有序排列* 满足这两个条件* @author Leon.Sun**/
public class TestSearch2 {public static void main(String[] args) {/*** 第一步干什么啊,给定数组*/int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };/*** 第二步给定要查找的值* 你要找谁,找key*/// int key = 2;/*** 10的索引是几*/int key = 10;/*** 再找一个6*/
//      int key = 6;/*** 进行查找* 这个查找叫折半查找或者叫二分查找*/
//      int index = -1;int index = binarySearch(array,key);/*** 输出结果* * 最终要返回他的索引*/if(index==-1) {System.out.println("不存在");}else {System.out.println(key + "的索引是" + index);}}/*** 你知道我们这里面该怎么办* 两种方案:* 第一个方案:不使用递归* @param array* @param key* @return*/public static int binarySearch(int[] array,int key) {/*** 首先指定low和high*/int low = 0;int high = array.length - 1;/*** 折半查找* * while一直查找* 如果low一直小于high就可以一直进行* 如果Low小于high就一直循环着,* 循环怎么办,* * 你看他什么时候循环就结束了,* 第一个return了就结束了* 找到了就结束了,还有一个循环完了就结束了* low大于high了及* 这里改成小于等于,* 所以有些细节方面,* 总体思路明白当是我们写代码的时候要注意细节,* 不使用递归的我们先想到这儿,* 这和递归有关系吗,* 折半查找还有递归* 差不多吧,我觉得和递归有关系* 有什么关系,* 首先这个数组我要进行折半查找,* 起始点是0,终止点是10,* 下一次我要在这个数组里面再次进行折半查找* 我们把这部分看成是一个数组呗,* 起始是0,这是4吗,* 下一次我要在这两个里面进行折半查找吗* 这是3这是4,* 递归查找,我们可以把数组的范围缩小* 指定他的起始和终止位置* 一直在进行折半查找* 我们的操作一直在重复* 从这个角度来说我们再来写一个折半查找的程序*/while(low<=high) {/*** 下一步要求得mid* * 这个mid半天没变过*/int mid = (low+high)/2;/*** 判断它是否等于* * 我们看一下这一步是不是可以省略* 直接进行折半查找就可以了* 是否等于,等于就直接返回* 这是key等于它*/if(key==array[mid]) {return mid;}else if(key<array[mid]) {/*** key小于array[mid],* 就是key是21,你找的是21,* 中间是56,是不是给high,low不用给* */high = mid-1;}else {/*** 这个else意味着一个含义* key>array[mid]*/low = mid + 1;                }           }/*** 实在找不到先返回-1* * 如果没找到就返回-1*/return -1;}}
package com.learn.search;/*** 这是我们说的折半查找* 折半查找给了大家两种思路,* 哪两种思路啊,* 第一个是非递归的,* 第二个是递归的,* 那非递归的告诉我时间复杂度是多少,* 然后空间复杂度* S(n) = O(1);* T(n) = O(log2 n)* 不管你循环了多少次,* 并没有分配更多的变量,* * 当我们采用的递归的话,* 递归怎么办,* 他是不是还是每次减少一半,* 这实现上还是差不多的,* T(n) = O(log2n);* 花的时间是差不多的,* 因为都是每次找一半,* 但是空间复杂度S(n)呢,* 每一次的空间复杂度是1,* 但是他这个方法调用了logn次呗* 我只调用一次这个方法是有限的,* 可是调用了log2 n次了,* 所以我们可以让1*log2n* S(n) = O(1*log2n);* 所以最后就是log2n* S(n) = O(log2 n);* 重复的调用,重复的分配空间,* 这样他花的空间就比较多的,* 从这个角度来说我们应该有哪一个,* 使用非递归的,* 那我们怎么还来讲一下递归的,* 在这个例子来说代码差不多* 就找这种分析问题的思路,* 扩展一下这种思路,* 也是可以这么来解决的,* 到这里我们就把线性表查找里的顺序查找和折半查找给大家讲了* 顺序查找非常的简单,折半查找是我们的一个重点,* 首先掌握算法,* 然后能写出代码,* 最后一步一定要知道折半查找的时间复杂度和空间复杂度* 尤其他的时间复杂度,logn这个性能非常高的,* * @author Leon.Sun**/
public class TestSearch3 {public static void main(String[] args) {int[] array = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };// int key = 2;
//      int key = 10;int key = 60;//      int index = -1;int index = binarySearch(array,key);if(index==-1) {System.out.println("不存在");}else {System.out.println(key + "的索引是" + index);}}/*** 我们要使用递归* 大家想一下,刚才我们使用递归的话,是什么不一样* 一样的是什么,不一样的是什么,* 这是一次递归,这又是一次递归,* 这还是一次递归,相同的是什么,* 你永远找到的是21,你找的数据永远在这儿,* 不同的是什么意思,* low和high不一样,范围不一样了* 初始状态从0到10* 那么基于这一点的话我们开始写程序了* 我们要进行这样的一个查找,* 我们要在这里面找这个值,* @param array* @param key* @return*/public static int binarySearch(int[] array,int key) {int low = 0;int high = array.length - 1;/*** 第一次找的话整个数组,key是21,low是0,high是最后一个元素* */return binarySearch(array, key, low, high);}/*** 我们增加两个参数,low和high* 因为每次调用array和key是相同的,* 但是low和high两个是一样的,这两个是不一样的* * 怎么来理解,一下子传入4个参数,* * 每次递归array和key都是一样的,* 不一样的是low和high* 两个都相当于指针,* * @param array* @param key* @param low* @param high* @return*/public static int binarySearch(int[] array,int key,int low,int high) {/*** 请问这里面该怎么写,递归* 首先要写递归的结束条件,* 如果low大于high了,* 你传进来的low已经大于high了,* 那就没找到呗,* 这是个结束条件* * low大于high,*/if(low>high) {return -1;}/*** 这是中间* * 获取mid*/int mid = (low+high)/2;/*** 找到就结束了*/if(key==array[mid]) {return mid;}else if(key<array[mid]) {/*** key找的是它,* 下面我要重复刚才的操作呗* 数据在array里面放着呢,* 查找的还是key,你现在找的是21,* 现在找到56这里了,我们要在前面的位置找,* low还是0,high等于mid-1,* low没有变,high=mid-1* * 我们都写上一个return* * 小于就递归查找*/return binarySearch(array, key, low, mid-1);}else {/*** 再来个else,就相当于key>array[mid]* 他在右边找,* 这是哪个内容,21大于19了,* high没变,low变了,* 还是要进行折半查找,* 那这个时候要怎么办,* 比如high没有变,* low变成mid+1,* 别忘了写了return* * 大于也递归查找*/return binarySearch(array, key, mid+1, high);}}}

顺序表查找+折半查找(二级)相关推荐

  1. c语言折半查找输出坐标,数据结构(C语言版)——有序表查找(折半查找)(代码版)...

    数据结构(C语言版)--有序表查找(折半查找)(代码版) 数据结构(C语言版)--有序表查找(折半查找)(代码版) #include #include #define ERROR 0 #define ...

  2. 二分查找/折半查找算法

    二分查找又称折半查找,优点是比较次数少,查找速度快,平均性能好:其缺点是要求待查表为有序表,且插入删除困难.因此,折半查找方法适用于不经常变动而查找频繁的有序列表.首先,假设表中元素是按升序排列,将表 ...

  3. 顺序查找 折半查找 二叉排序树

    1.顺序查找,折半查找,二叉排序树操作定义 SeqSearch.h #include<stdio.h> #define ARRAYLEN 8int source[]={69, 65, 90 ...

  4. 数据结构 查找 静态查找表算法 折半查找 二叉排序树查找算法 实验报告

    实验内容: 基本内容: 算法1:采用顺序存储结构创建静态查找表,对查找表进行顺序查找和改进的顺序查找,并对其查找效率进行比较: 算法2:采用顺序存储结构创建静态查找表--有序表,对有序表进行二分查找: ...

  5. 顺序表插入删除查找操作

    线性表实验 一.实验目的 1.掌握线性表的顺序存储结构 2.验证顺序表及其基本操作的实现 3.理解算法与程序的关系们能够将顺序表算法转换为对应的程序 二.实验步骤 1.建立含有若干个元素的顺序表 2. ...

  6. Python二分查找/折半查找算法详解--(面试常考)

    https://blog.csdn.net/hanhanwanghaha宝藏女孩 欢迎您的关注! 欢迎关注微信公众号:宝藏女孩的成长日记 如有转载,请注明出处(如不注明,盗者必究)   二分查找也称折 ...

  7. C语言数组查找(线性查找 折半查找)

    线性查找 #include <stdio.h> #include <math.h>void find_nine(int numbers[]) {int i;for(i = 0; ...

  8. swift版 二分查找 (折半查找)

    二分查找作为一种常见的查找方法,将原本是线性时间提升到了对数时间范围之内,大大缩短了搜索时间,但它有一个前提,就是必须在有序数据中进行查找.废话少说,直接上代码,可复制粘贴直接出结果! import ...

  9. php折半查找算法,二分查找 [折半查找] 算法 PHP 版

    查找表:就是同一类型的数据元素构成的数据集合 有静态表和动态表 本文实现PHP版的二分查找算法[本算法仅用于顺序存储的查找表] /** * Created by PhpStorm. * User: 1 ...

最新文章

  1. 如何同时安装Office2003和Office2007!
  2. 不同年龄段给狗狗起名字,我命中了,你呢?
  3. html js绑定键盘按键触发事件(按回车键登陆)
  4. 使用python发送邮件和接收邮件
  5. puppy linux不识别鼠标,不止于OS X!还有适用于Mac的八款替代操作系统
  6. .NET Core开发日志——Middleware
  7. SQL学习——小结练习(1)
  8. Linux内存管理 -- /proc/{pid}/smaps讲解
  9. 现代软件工程—构建之法---第四章:练习与讨论
  10. 学习HanNLP2015年12月4日 16:24:53
  11. less 、more 翻页显示文件内容
  12. 搜狗拼音输入法下载|搜狗拼音输入法下载
  13. Android 面试题(答案最全) 转:http://www.jobui.com/mianshiti/it/android/2682/
  14. IDEA补丁破解使用方法
  15. 78岁老人爱上玩乐器硬是学会了吹奏萨克斯
  16. unreal engine各个版本网盘离线下载
  17. 查看树莓派I2C设备是否正常
  18. 国产化飞腾CPU主板安装统信专业版桌面OS,以及统信OS如何进root用户
  19. 北大韦神等十人获奖,均分1000万元,达摩院2021青橙奖出炉
  20. Robotframwork-ride 启动异常解决

热门文章

  1. Oracle数据库三种备份方案
  2. mongodb 入门笔记
  3. 容器资源需求、资源限制(二十二)
  4. leetcode讲解--872. Leaf-Similar Trees
  5. 【日常小记】linux中强大且常用命令:find、grep
  6. Spring MVC之表单标签
  7. symantec 5220牛刀小试系列(二)
  8. 华为S2326 TP-EI交换机如何做端口镜像
  9. 角色权限模块设计-数据pdm
  10. 孕妇可以使用计算机,【电脑对孕妇有影响吗】电脑对孕妇的危害,孕妇能玩电脑吗 - 妈妈网百科...