认识时间复杂度
常数时间的操作:一个操作如果和数据量没有关系,每次都是固定时间内完成的操作,叫做常数操作。
时间复杂度为一个算法流程中,常数操作数量的指标。常用O(读作big O)来表示。具体来说,在常数操作数量的表达式中,只要高阶项,不要低阶项,也不要高阶项的系数,剩下的部分如果记为f(N),那么时间复杂度为O(f(N))。
评价一个算法流程的好坏,先看时间复杂度的指标,然后再分析不同数据样本下的实际运行时间,也就是常数项时间。
冒泡排序细节复杂度分析
代码示例:
//冒泡排序
//时间复杂度: O(N^2)
public class Code_00_BubbleSort {
public static void bubbleSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int end = arr.length - 1; end > 0; end--) {
for (int i = 0; i < end; i++) {
if (arr[i] > arr[i + 1]) {
swap(arr, i, i + 1);
}
}
}
}
//交换方法
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
N个数字要排序完成,总共进行N-1趟排序,每i趟的排序次数为(N-i)次,所以可以用双重循环语句,外层控制循环多少趟,内层控制每一趟的循环次数
综上所述:冒泡排序总的平均时间复杂度为:O(n2) 。
选择排序复杂度分析
代码示例:
//选择排序
//时间复杂度: O(N^2)
public class Code_02_SelectionSort {
public static void selectionSort(int[] arr) {
//如果数组为空或者数组长度为1直接返回
if (arr == null || arr.length < 2) {
return;
}
for (int i = 0; i < arr.length - 1; i++) {
//定义一个初始最小值的索引
int minIndex = i;
for (int j = i + 1; j < arr.length; i++) {
//找出最小值的索引
minIndex = arr[j] < arr[minIndex] ? j : minIndex;
}
//把最小值和arr[i]交换
swap(arr, i, minIndex);
}
}
//交换方法
public static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
选择排序的时间复杂度:简单选择排序的比较次数与序列的初始排序无关。 假设待排序的序列有 N 个元素,则比较次数永远都是N (N - 1) / 2。而移动次数与序列的初始排序有关。当序列正序时,移动次数最少,为 0。当序列反序时,移动次数最多,为3N (N - 1) / 2。
所以,综上,简单排序的时间复杂度为 O(N2)。
插入排序复杂度分析
代码示例:
//插入排序
// 相当于摸牌: 在每次摸牌时如果小往前走,每一次摸完牌手上都是有序的牌
//时间复杂度和数据状况有关:
// 如果每次摸牌的都是最大的时间复杂度为:O(N)
// 如果每次摸牌的都是最小的时间复杂度为:O(N^2)
// 遇到这种情况一律按最差情况处理: 时间复杂度O(N^2)
public class Code_01_InsertionSort {
public static void insertSort(int[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int i = 1; i < arr.length; i++) {
for (int j = i - 1; j >= 0 && arr[j] > arr[j + 1]; j--) {
swap(arr, j, j + 1);
}
}
}
public static void swap(int[] arr, int i, int j) {
/*arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];*/
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
插入排序相当于摸牌:在每次摸牌时如果摸牌比手牌最后一张小则往前走直到遇到比手牌大的地方插入,每一次摸完牌手上都是有序的牌
时间复杂度和数据状况有关:
如果每次摸牌的都是最大的时间复杂度为:O(N)
如果每次摸牌的都是最小的时间复杂度为:O(N^2)
遇到这种情况一律按最差情况处理: 时间复杂度O(N^2)