数据结构和算法【线性查找】

算法与数据结构

                          希望可以和 大家一起学习 慢慢来 行则将至 !  

image-20240113165344114

希望 大家学习的时候

  • 不仅仅是学习算法与数据结构,更是深刻理解计算机科学

学算法和数据结构到底有没有用?

什么是程序?
image-20240113171224529

算法在生活中的一些实际应用:

文件的压缩都使用了 压缩算法

image-20240113171921194

游戏的寻址: 包含了 寻路算法 和 智能算法

image-20240113172057595

image-20240113172156459

那为什么我在生活,工作中,用不到算法和数据结构?

是因为业务层面应用的不多 但基本都在业务层 而不是基础层

什么是算法?

Algorithm 的本意: 解决问题的方法

算法是一系列解决问题的,清晰,可执行的计算机指令。

生活中 也有算法:

比如 如何求解一元二次方程? 菜谱 如何去往一个确定的地方

算法包含

  • 有限性
  • 确定性: 不会产生二义性
  • 可行性
  • 输入
  • 输出

1 线性查找(LinearSearch)

本身是一个非常简单的算法

比如 在一沓试卷中,找到属于自己的那张试卷

那我们怎么做呢 我们一张一张的翻阅看是不是自己的试卷

也就是 一个一个的去找自己想要的元素 这样的做法就是线性查找法

需求示例:

image-20240113173950039

开始: 实现线性查找

LinearSearch 线性查找算法

逻辑处理:

package src;
/**
 * @author xxz
 * @Created on: 2024-01-13 21:03
 * @version 1.0
 * @Description: 线性查找算法
 */
public class LinearSearch {
    //函数名 search   参数 data 和 target
    public int search(int[] data, int target ){
        for (int i = 0; i < data.length; i++) {
            if (data[i] == target)
                return i;
        }
        return  -1;
    }
    // 测试写的算法
    public static void main(String[] args){
        int[] data = { 24, 18, 12, 9, 16, 66, 32, 4};  // 定义数组
        LinearSearch ls =new LinearSearch();
        //调用方法 并传入两个参数  1  传入数组 2 要查找的目标值
        int res = ls.search(data, 16);
        //  返回结果记作   res
        System.out.println(res);// 控制台打印结果

        //继续测试不存在的值
        int res2 = ls.search(data, 666);
        System.out.println(res2);
    }
}

image-20240113212140195

现在 逻辑实现完成

接下来我们进行优化操作

优化1

思路:

  • 将方法 search 方法 直接写为 static 静态的方法用户使用的时候直接调用而不用再去new对象
  • 不希望用户去创建 LinearSearch 对象 所以我们将构造函数声明为私有的
package src;
/**
 * @author xxz
 * @Created on: 2024-01-13 21:03
 * @version 1.0
 * @Description: 线性查找算法
 */
//优化版   优化思路将方法 直接写为 static 用户使用的时候直接调用而不用再去new对象
public class LinearSearch {
    // 为了避免用户去使用 new LinearSearch对象 可以私有化构造函数
    private LinearSearch(){}
    //函数名 search   参数 data 和 target
    public  static int search(int[] data, int target ){
        for (int i = 0; i < data.length; i++) {
            if (data[i] == target)
                return i;
        }
        return  -1;
    }
    // 测试写的算法
    public static void main(String[] args){
        int[] data = { 24, 18, 12, 9, 16, 66, 32, 4};  // 定义数组
        //将方法写为静态方式 就不需要重新new  而可以直接调用 加了static 去掉此步骤 LinearSearch ls =new LinearSearch();
        int res = LinearSearch.search(data, 16);
        //  返回结果记作   res
        System.out.println(res);// 控制台打印结果

        //继续测试不存在的值
        int res2 = LinearSearch.search(data, 666);
        System.out.println(res2);
    }
}

但是我们现在的search 方法 因为参数是 int 类型 所以这个 search 方法只能处理 int 类型的数据

但我们实际中用户可能是其他类型 那时候这个线性查找算法的方法就无法查找了 所以还需要优化。

优化2

处理类型的局限

在java语言中有专门处理不同类型的语言机制 ===》 泛型

而在java中最常用使用泛型的方式 就是定义一个泛型类 而此算法中我们要是将类 LinearSearch 定义为泛型类是不起作

用的, 我们在这应该将 search 方法 定义为泛型方法

如何定义泛型方法

image-20240113214204796

添加 <> 并起名 T 参数也随之改变为T 这样用户使用什么类型 那么到时候 数据类型就随着用户的指定使用而改变

image-20240113214349820

java中 泛型只能接受类对象 而不能接受 基本数据类型 而int 是基本数据类型 所以不能被接受 因该使用 包装类

image-20240113215432501

泛型的使用:

java中 泛型只能接受类对象 而不能接受 基本数据类型 而int 是基本数据类型 所以不能被接受 因该使用 包装类

image-20240113214918088

最终优化版:

package src;
/**
 * @author xxz
 * @Created on: 2024-01-13 21:03
 * @version 1.0
 * @Description: 线性查找算法
 */
public class LinearSearch {
    private LinearSearch(){}
    
    public  static<T> int search(T [] data, T target ){
        for (int i = 0; i < data.length; i++) {
         //   if (data[i] == target)   // 由于使用了泛型  我们这里的data i 已经不是基本数据类型了所以这里也需要修改 这里因该为类对象的判断    
         //这里因该为类对象的判断   !!!!!!!! 因为泛型的使用  
            if(data[i].equals(target))
            return i;
        }
        return  -1;
    }
    // 测试写的算法
    public static void main(String[] args){
        // 使用泛型来处理参数类型限制 需要使用包装类来接受对象
        Integer[] data = { 24, 18, 12, 9, 16, 66, 32, 4};  // 定义数组
        
        int res = LinearSearch.search(data, 16);
        System.out.println(res);// 控制台打印结果

        int res2 = LinearSearch.search(data, 666);
        System.out.println(res2);
    }
}

测试: 自己设计一个学生类

package src;
/**
 * @author xxz
 * @version 1.0
 * @Created on: 2024-01-13 22:06
 * @Description: 自己设计的学生类
 */
public class Student {
         private String name;
         public Student(String name){
             this.name = name;
         }
}
public class LinearSearch {
    private LinearSearch(){}
    public  static<T> int search(T [] data, T target ){
        for (int i = 0; i < data.length; i++) {
            if(data[i].equals(target))
                return i;
        }
        return  -1;
    }
    // 测试写的算法
    public static void main(String[] args){
    
        // 学生类测试用例
        Student[] students = {
                               new Student("xx"),
                               new Student("BB"),
                               new Student("CC"),
                               };
        Student bb = new Student("CC");   // 因为存在 应该输出 正确
        int res3 =LinearSearch.search(students,bb);
        System.out.println(res3);
    }

测试结果是 -1 不存在 可是我们数据明明是存在的 问题出在哪里呢?

问题出现在 equals 方法比较的对象 我们不需要比较地址 而是需要比较字符串是否相等

所以我们需要去覆盖 equals 这个方法

这个 equals 的逻辑是可以由 Student 类的设计者来提供的

package src;
/**
 * @author xxz
 * @version 1.0
 * @Created on: 2024-01-13 22:06
 * @Description: 自己设计的学生类
 */
public class Student {
         private String name;
         public Student(String name){
             this.name = name;
         }
         // 声明函数   进行 equals 方法的覆盖 来进行字符串的判断
        // 这样当 使用这个 search方法的时候就走的这个覆盖后的方法 而不是之前的方法
          @Override
          public boolean equals(Object student){
             //标准套路
              if(this == student)
                  return true;
              if(student == null)
                  return false;
              if(this.getClass() != student.getClass())
                  return false;

             Student another = (Student)student;
             return this.name.equals(another.name);
          }
}

image-20240113222429180

  • 36
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值