常见算法
查找算法
查询某个元素是否存在
二分查找(数组元素必须是有序的)
package exercise;
public class exercise1 {
public static void main(String[] args) {
int[] arr = {7, 23, 797, 23, 79, 81, 103, 127, 131, 147};
System.out.println(binarySearch(arr, 131));
}
public static boolean binarySearch(int[] arr, int num) {
int min = 0;
int max = arr.length - 1;
while (min <= max) {
int mid = (max + min) / 2;
if (num > arr[mid]) {
min = mid + 1;
} else if (num < arr[mid]) {
max = mid - 1;
} else {
return true;
}
}
return false;
}
}
插值查找
二分查找优化
适合数据分布比较均匀的情况
斐波那契查找
根据黄金分割点查找
分块查找
有一定规律
定义块类
分块查找
无规律
每个块内的数字范围没有交集
哈希查找
排序算法
冒泡排序
要点
public static int[] maoPao(int[] arr) {
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];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
return arr;
}
选择排序
public static int[] selection(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i +1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
插入排序
public static int[] insert(int[] arr) {
int startIndex = -1;
for (int i = 0; i < arr.length - 1; i++) {
if (arr[i] > arr[i + 1]) {
startIndex = i + 1;
break;
}
}
for (int i = startIndex; i < arr.length; i++) {
int j = i;
while (j > 0 && arr[j] < arr[j - 1]) {
int temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
j--;
}
}
return arr;
}
快速排序
递归算法
自己调用自己的方法
心得:方法内部再次调用方法的时候,参数必须要更加的靠近出口
Return返回的结果是给调用者的
.
public static void quickSort(int[] arr, int i, int j) {
//定义两个变量记录要查找的范围
int start = i;
int end = j;
if(start > end){
//递归的出口
return;
}
//记录基准数
int baseNumber = arr[i];
//利用循环找到要交换的数字
while(start != end){
//利用end,从后往前开始找,找比基准数小的数字
//int[] arr = {1, 6, 2, 7, 9, 3, 4, 5, 10, 8};
while(true){
if(end <= start || arr[end] < baseNumber){
break;
}
end--;
}
System.out.println(end);
//利用start,从前往后找,找比基准数大的数字
while(true){
if(end <= start || arr[start] > baseNumber){
break;
}
start++;
}
//把end和start指向的元素进行交换
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
//当start和end指向了同一个元素的时候,那么上面的循环就会结束
//表示已经找到了基准数在数组中应存入的位置
//基准数归位
//就是拿着这个范围中的第一个数字,跟start指向的元素进行交换
int temp = arr[i];
arr[i] = arr[start];
arr[start] = temp;
//确定6左边的范围,重复刚刚所做的事情
quickSort(arr,i,start - 1);
//确定6右边的范围,重复刚刚所做的事情
quickSort(arr,start + 1,j);
}
可不可以先移动start指针再移动end指针呢?
如果先移动start,则有可能把一个大于基准数的元素移动到前面去
所以要先移动end,这样就可以保证要把一个小于基准数的元素移动到前面去
Arrays
二分查找有细节
拷贝数组
默认是升序
排序重载
Sort(数组,排序顺序)
只能给引用数据类型排序
O1 - o2 升序
O2 - o1 降序
Lambda
简化匿名内部类
函数式编程
JDK8开始有的
0
只能是只有一个抽象方法的接口才可以用这个lambda
可以用@FunctionalInterface来判断
练习
package exercise;
import java.util.Arrays;
public class exercise8 {
public static void main(String[] args) {
Girl girl1 = new Girl("sdf", 22, 160);
Girl girl2 = new Girl("dc", 22, 162);
Girl girl3 = new Girl("sdc", 22, 160);
Girl[] girlsArr = {girl1, girl2, girl3};
Arrays.sort(girlsArr, (o1, o2) -> {
if (o1.getAge() != o2.getAge()) {
return o1.getAge() - o2.getAge();
}
if (o1.getHeight() != o2.getHeight()) {
return o2.getHeight() - o1.getHeight();
}
return o1.getName().compareTo(o2.getName());
});
System.out.println(Arrays.toString(girlsArr));
}
}
斐波那契数列
package exercise;
public class exercise9 {
public static void main(String[] args) {
System.out.println(rabbit(12));
}
public static int rabbit(int month) {
if (month == 1 || month == 2) {
return 1;
}
return rabbit(month - 1) + rabbit(month - 2);
}
}
反向递归
package exercise;
public class exercise10 {
public static void main(String[] args) {
System.out.println(peach(1));
}
public static int peach(int day) {
if (day == 10) {
return 1;
}
return (peach(day + 1) + 1) * 2;
}
}
爬到第20阶
只有两种方法:1、19阶的爬法+爬一阶,2、18阶的爬法+爬两阶
同理
爬到第19阶
只有两种方法:1、18阶的爬法+爬一阶,2、17阶的爬法+爬两阶
。。。
爬到第3阶
1、2阶的爬法+爬一阶,2、1阶的爬法+爬两阶 (共2+1种,是爬到第1阶的方法
+爬到第2阶的方法)
爬到第2阶
1阶的爬法+爬一阶,0阶爬两阶 (共2种)
爬到第1阶
1阶爬一阶 (共1种)
package exercise;
public class exercise11 {
public static void main(String[] args) {
System.out.println(stairs(20));
}
public static int stairs(int sum){
if (sum == 1) {
return 1;
}
if (sum == 2){
return 2;
}
return stairs(sum - 1) +stairs(sum - 2);
}
}