数组的查找(搜索)
查找的分类
- 线性查找
- 二分法查找
线性查找
按照顺序查找
String [ ] a= new String a []{"ab","abc","abcd"};
String dest ="abcd";
boolean isFlag=true;
for(int i = 0;i<a.length;i++){
if(dest.equals(a[i])){
System.out.println("已找到指定元素");
isFlag=false;
break;
}
}
if(isFlag){
System.out.println("未找到指定元素");
}
二分法查找
二分法查找的数组必须有序。
折半查找 把数组分成2份
int[ ] a= new inta []{11,22,33,44,55,66,77,88,99,10};
int dest =33;
boolean isFlag=true;
for(int i = 0;i<a.length;i++){
if(dest.equals(a[i])){
System.out.println("已找到指定元素");
isFlag=false;
break;
}
}
if(isFlag){
System.out.println("未找到指定元素");
}
数组排序
通常来说排序的目的都是为了快速查找
衡量排序算法的优劣:
- 时间复杂度:分析关键字的比较次数喝记录的移动次数
- 空间复杂度:分析排序算法中需要多少辅助内存
- 稳定性:若两个记录A和B的关键字值相等,但排序后A、B的先后次序保持不变,则称这种排序算法是稳定的
排序算法分类:内部排序和外部排序
内部排序:整个排序过程不需要借助外部存储器(磁盘),所有排序操作都在内存中完成。
外部排序:参与排序的数据非常多,数据量非常大,计算机无法把整个排序过程放在内存中完成,必须借助外部存储器(磁盘)。外部排序最常见的是多路归并排序。可以认为外部排序是由多次内部排序组成。
十大内部排序算法
- 选择排序—直接选择排序、堆排序
- 交换排序—冒泡排序、快速排序
- 插入排序—直接插入排序、折半插入排序、Shell排序
- 归并排序
- 桶式排序
- 基数排序
算法的五大特征
- 输入
- 输出
- 有穷性
- 确定性
- 可行性
冒泡排序
什么是冒泡排序:冒泡排序就是一次比较两个元素,如果它们的顺序错误就把它们交换过来。然后再比较下一个直到比较完所有的元素。
int [] arr = new int []{11,32,1,45,76,99,23,5};
for(int i=0;i<arr.length-1;i++){
for(int j = 0;j<arr.length-1-i;j++){
if(arr[j]>arr[j+1]){
int temp= arr[j+1];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
快速排序
package sort;
public class QuickSort {
private static int[] a = {6,1,2,7,9,3,4,5,10,8};
public static void main(String[] args){
System.out.println("原数组值:");
for (int i : a) {
System.out.print(i+" ");
}
System.out.println();
quickSort(0, a.length-1);
}
public static void quickSort(int left,int right){
int i,j,temp;
if(left>right){
return;
}
temp=a[left]; //temp中存的就是基准数
i=left;
j=right;
while(i!=j){
//顺序很重要,要先从右边开始找 ,直到找到一个小于基准的值
while(a[j]>=temp && i<j){
j--;
}
//再找右边的 ,直到找到一个大于基准的值
while(a[i]<=temp && i<j){
i++;
}
//交换两个数在数组中的位置
if(i<j) {
int t=a[i];
a[i]=a[j];
a[j]=t;
System.out.println("交换值后:");
for (int k : a) {
System.out.print(k+" ");
}
System.out.println();
}
}
//最终将基准数归位
a[left]=a[i];
a[i]=temp;
System.out.println("基准值归位后:");
for (int k : a) {
System.out.print(k+" ");
}
System.out.println();
if(left<i-1){
quickSort(left,i-1);//继续处理左边的,这里是一个递归的过程
}
if(right>j+1){
quickSort(i+1,right);//继续处理右边的 ,这里是一个递归的过程
}
}
}//转载自https://blog.csdn.net/qq_38741971/article/details/81661144
算法排序的性能对比
Arrays工具类的几个常用方法
- Arrays.equals(int [] a,int[]b) -判断两个数组是否相等 返回 true 或者false
- Arrays.toString(int [] a) -输出数组信息 返回String
- Arrays.fill(int []a ,int val) -将指定值填充到数组之中
- Arrays.sort(int [] a) -对数组继续排序
- Arrays.binarySearch(int [] a,int key) -对排序后的数组进行二分法检索指定的值 ,如果查找的值不存在 返回负数
数组的两个常见异常
- ArrayIndexOutOfBoundsExcetion 数组越界异常
- NullPointerException 空指针异常
面向对象
面向对象的三大特征
3. 封装
4. 继承
5. 多态
面向对象程序设计的重点是类的设计,设计类就是设计类的成员。
类里的成员有 属性和行为
属性:对应类中的成员变量
行为:对应类中的成员方法
每一个对象都有一份自己的独立空间,同一个方法能有好多个对象。
成员变量(全局变量)和局部变量的区别
相同点:
1.定义变量的格式相同—数据类型 变量名 = 变量值
2. 先声明后使用
3. 变量都有其对应的作用域
不同点:
1.声明的位置不同;
2.成员变量直接定义在类的一对{}内;
3.局部变量声明在方法内、方法形参、代码块内、构造器形参、构造器内部的变量、
变量的默认初始化值
全局变量:
整型(byte、short、int 、long):0
浮点型(float、double):0.0
字符型(char):0 或者‘\u0000’
布尔型(boolean):false
引用型(类、接口、数组):null
局部变量没有初始化值!
方法的修饰符
【可访问性修饰符】【abstract】【static】【final】【native】【synchronize】返回类型 方法名(参数表)【throws 异常类名表】
{
//方法体
}
【可访问性修饰符】:与成员变量的访问修饰符的作用和方法一样。
【abstract】:修饰词abstract修饰的为抽象方法,仅含有方法的声明部分,而没有方法体和具体的操作实现部分的方法。那么为什么不定义方法的实现呢?链接
【static】:static修饰的方法是属于整个类的方法,简称类方法。当第一次调用含有类方法的类时,系统只为该类的类方法创建一个版本。这个版本被该类和所有实例所共享。
与之对应,无static修饰的方法为的实例方法。注意:类方法不能直接访问实例变量;实例方法可以对当前对象的实例变量进行操作,而且可以访问类变量。
【final】:最终方法。最终方法是不能被当前类的子类重新定义的方法(注:所有已被private修饰符限定为私有的方法以及所有包含在final类中的方法,都被默认为是final的)。
【native】:本地方法。一般用来声明用其他语言(C、C++、FORTRAN和汇编等)书写方法体的特殊方法。
【synchronize】:若synchronized修饰的方法是一个类方法,那么在这个方法被调用执行前,将把系统类Class中对应当前类的对象加锁;
return关键字
return关键字的用法,它包括两方面,它代表已经做完,离开此方法,其次代表此方法产生了一个值,这个值要放在return语句后面,返回此值。
如果方法的返回类型是void,那return关键字的作用只是用来退出方法。