算法与数据结构
希望可以和 大家一起学习 慢慢来 行则将至 !
希望 大家学习的时候
- 不仅仅是学习算法与数据结构,更是深刻理解计算机科学
学算法和数据结构到底有没有用?
什么是程序?
算法在生活中的一些实际应用:
文件的压缩都使用了 压缩算法
游戏的寻址: 包含了 寻路算法 和 智能算法
那为什么我在生活,工作中,用不到算法和数据结构?
是因为业务层面应用的不多 但基本都在业务层 而不是基础层
什么是算法?
Algorithm 的本意: 解决问题的方法
算法是一系列解决问题的,清晰,可执行的计算机指令。
生活中 也有算法:
比如 如何求解一元二次方程? 菜谱 如何去往一个确定的地方
算法包含
- 有限性
- 确定性: 不会产生二义性
- 可行性
- 输入
- 输出
1 线性查找(LinearSearch)
本身是一个非常简单的算法
比如 在一沓试卷中,找到属于自己的那张试卷
那我们怎么做呢 我们一张一张的翻阅看是不是自己的试卷
也就是 一个一个的去找自己想要的元素 这样的做法就是线性查找法
需求示例:
开始: 实现线性查找
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);
}
}
现在 逻辑实现完成
接下来我们进行优化操作
优化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 方法 定义为泛型方法
如何定义泛型方法
添加 <> 并起名 T 参数也随之改变为T 这样用户使用什么类型 那么到时候 数据类型就随着用户的指定使用而改变
java中 泛型只能接受类对象 而不能接受 基本数据类型 而int 是基本数据类型 所以不能被接受 因该使用 包装类
泛型的使用:
java中 泛型只能接受类对象 而不能接受 基本数据类型 而int 是基本数据类型 所以不能被接受 因该使用 包装类
最终优化版:
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);
}
}