今天主要给大家讲解JAVA常考点之数据结构与算法,内容有点小长,希望大家耐心看完哈
目录
1、二分查找 1
2、冒泡排序 3
3、层序遍历二叉树 4
4、选择排序 5
5、反转单链表 6
6、插入排序 7
7、判断链表是否有环 8
8、快速排序 11
9、求二叉树最大的深度(宽度) 12
10、爬楼梯 13
11、合并两个有序链表 14
12、数组的最大子序和 16
13、求两个数的最大公约数与最小公倍数 17
14、堆排序 18
15、最长回文子串 20
1、二分查找
优点是比较次数少,查找速度快,平均性能好;
其缺点是要求待查表为有序表,且插入删除困难。
因此,折半查找方法适用于不经常变动而查找频繁的有序列表。
使用条件:查找序列是顺序结构,有序。
时间复杂度
采用的是分治策略
最坏的情况下两种方式时间复杂度一样:O(log2 N)
最好情况下为O(1)
空间复杂度
算法的空间复杂度并不是计算实际占用的空间,而是计算整个算法的辅助空间单元的个数
非递归方式:
由于辅助空间是常数级别的所以:
空间复杂度是O(1);
递归方式:
递归的次数和深度都是log2 N,每次所需要的辅助空间都是常数级别的:
空间复杂度
:
(1)非递归实现
public static int binarySearch(int[] arr, int key) {
int low = 0;
int high = arr.length - 1;
//当要查询的数小于最小值或大于最大值时,直接返回,不需要进入while循环内部
if (key < arr[low] || key > arr[high]) {
return -1;
}
while (low <= high) {
int middle = (low + high) / 2;
if (key == arr[middle]) {
return middle;
} else if (key < arr[middle]) {
high = middle - 1;
} else {
low = middle + 1;
}
}
return -1;
}
(2)递归实现
public static int recursionBinarySearch(int[] arr, int key, int low, int high) {
int middle = (low + high) / 2;
if (key < arr[low] || key > arr[high]) {
return -1;
}
if (key == arr[middle]) {
return middle;
} else if (key < arr[middle]) {
return recursionBinarySearch(arr, key, low, middle - 1);
} else {
return recursionBinarySearch(arr, key, middle + 1, high);
}
}
2、冒泡排序
比较两个相邻的元素,若第二个元素比第一个元素小,则交换两者的位置,第一轮比较完成后,最大的数会浮到最顶端。排除此最大数,继续下一轮的比较。
时间复杂度:O(N^2)
空间复杂度:O(1)
为稳定排序
可以为冒泡排序进行优化,当某一趟未发生交换时,则说明数组已经有序了,无需再进行排序。
public static void bubbleSort(int[] arr) {
//一共需要进行n-1趟循环
for (int i = 0; i < arr.length - 1; i++) {
//假设本次循环中,没有发生交换
boolean flag = false;
//本次循环一共需要比较n-i-1次
for (int j = 0; j < arr.length - i - 1; j++) {
if (arr[j + 1] < arr[j]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
//本次循环发生交换了
flag = true;
}
}
//如果本次循环后,未发生交换,则表明数组有序,退出排序
if (!flag) {
break;
}
}
}
3、层序遍历二叉树
结点类
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
层序遍历(非递归)
public void layerOrder(TreeNode root) {
LinkedList list = new LinkedList<>();
TreeNode t;
if (root != null) {
list.push(root);
}
while (!list.isEmpty()) {
t = list.removeFirst();
System.out.print(t.getValue());
if (t.getLeft() != null) {
list.addLast(t.getLeft());
}
if (t.getRight() != null) {
list.addLast(t.getRight());
}
}
}
4、选择排序
第一轮从整个数组中选择最小的数,与第一个数交换。
第二轮排除第一个数,从剩下来的数中选择最小的数,与第二个数交换。
以此类推。
时间复杂度:O(N^2)
空间复杂度:O(1)
为稳定排序
时间复杂度:O(N^2)
空间复杂度:O(1)
为稳定排序