时间复杂度
一个算法流程中 最坏情况 的,常数操作数量的指标。评价算法好坏,先看时间复杂度指标,在分析不同数据下的实际运行时间。比如,对于冒泡和和选择而言,时间复杂度固定为O(n2),而对于插入排序最好的情况为O(n),最坏情况为O(n2),一般都是取最坏情况作为算法的时间复杂度。
常数操作
操作与数据量大小无关。
对数器
1、有一个待测的方法a
2、实现一个绝对正确但复杂度不好的方法b
3、实现一个随机样本产生器
4、把方法a和方法b比对很多次来验证a是否正确
5、如果有一个样本比对出错,打印样本分析是哪个出错
6、当样本数量很多时比对也依然正确,则方法a正确
这个用于笔试,或者网上oj不靠谱的情况,要提前准备好模板,来验证正确与否。
递归的剖析
所谓递归函数就是系统栈的使用。
递归的复杂度分析:
master公式只能用在划分的子集规模一样的情况下。
使用的例子:归并排序
作业
1、完成冒泡、选择、插入、归并排序,并记好他们对应的时间复杂度。
2、完成小和问题。
作业完成
1、冒泡排序
先看自己完成的版本。
package niuke;
import java.util.Arrays;
public class bubbleSort {
//冒泡排序,从小到大排序
public static void bubblesort(int[] arr) {
if(arr.length <=1)
return;
for(int i = 0; i < arr.length-1; i++) {
for(int j = 0; j < arr.length-i-1; j++) {
if(arr[j] > arr[j+1]) {
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
}
//打印数组,测试用。
public static void printarr(int[] arr) {
for(int i = 0; i <= arr.length-1; i++) {
System.out.print(arr[i] + " ");
}
System.out.println(" ");
}
//运用对数器测试冒泡排序,正确打印Nice,错误打印Fucking Fucked。
public static void main(String[] args) {
int[] res = {0,0,0,0,0,0,0,0,0,0};
int[] res1 = {0,0,0,0,0,0,0,0,0,0};
for(int i = 0; i < 10; i++) {
int ran = (int) (Math.random()*10 +8) - (int) (Math.random()*10 +2);
res[i] = ran;
res1[i] = ran;
}
bubblesort(res);
Arrays.sort(res1);
if(Arrays.equals(res, res1))
System.out.println("Nice!");
else System.out.println("Fucking Fucked");
}
}
显然,冒泡排序时间复杂度严格为O(n2),与数据量无关。
2、选择排序
首先还是自己完成的版本。
package niuke;
import java.util.Arrays;
public class chooseSort {
public static void choosesort(int[] arr) {
if(arr.length <= 1)
return;
int j,i;
for(i = 0; i <= arr.length-1; i++) {
int maxindex = i;
for(j = i+1; j <= arr.length-1; j++) {
if(arr[j] < arr[maxindex]) {
int tmp = arr[j];
arr[j] = arr[maxindex];
arr[maxindex] = tmp;
}
}
}
}
public static void printarr(int[] arr) {
for(int i = 0; i <= arr.length-1; i++) {
System.out.print(arr[i] + " ");
}
System.out.println(" ");
}
public static void main(String[] args) {
int[] res = {0,0,0,0,0,0,0,0,0,0};
int[] res1 = {0,0,0,0,0,0,0,0,0,0};
for(int i = 0; i < 10; i++) {
int ran = (int) (Math.random()*10 +8) - (int) (Math.random()*10 +2);
res[i] = ran;
res1[i] = ran;
}
Arrays.sort(res1);
//printarr(res1);
choosesort(res);
//printarr(res);
if(Arrays.equals(res, res1))
System.out.println("Nice!");
else System.out.println("Fucking Fucked");
}
}
同样,每次都要遍历数组,固定为O(n2),并且不随着数据量增加而改变。
3、插入排序
首先看看自己写的代码。
package niuke;
import java.util.Arrays;
public class insertSort {
//插入排序,i是被比较的。
public static void insertsort(int[] arr) {
if(arr.length <= 1)
return;
for(int i = 1; i <= arr.length-1; i++) {
for(int j = i-1; j >=0 && arr[j] > arr[j + 1]; j--) {
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
//for test
public static void printarr(int[] arr) {
for(int i = 0; i <= arr.length-1; i++) {
System.out.print(arr[i] + " ");
}
System.out.println(" ");
}
//for test
public static void main(String[] args) {
int[] res = {0,0,0,0,0,0,0,0,0,0};
int[] res1 = {0,0,0,0,0,0,0,0,0,0};
for(int i = 0; i < 10; i++) {
int ran = (int) (Math.random()*10 +8) - (int) (Math.random()*10 +2);
res[i] = ran;
res1[i] = ran;
}
Arrays.sort(res1);
printarr(res1);
insertsort(res);
printarr(res);
if(Arrays.equals(res, res1))
System.out.println("Nice!");
else System.out.println("Fucking Fucked");
}
}
4、归并排序
package niuke;
import java.util.Arrays;
public class mergeSort {
public static void Mergesort(int[] arr) {
if(arr.length <=1) {
return;
}
Mergesort(arr,0,arr.length-1);
}
public static void Mergesort(int[] arr,int lindex,int rindex) {
if(lindex == rindex) {
return;
}
int middle = (rindex + lindex)/2;
Mergesort(arr,lindex,middle);
Mergesort(arr,middle+1,rindex);
merge(arr,lindex,middle,rindex);
}
public static void merge(int[] arr, int l, int m, int r) {
int[] help = new int[r - l + 1];
int i = 0;
int p1 = l;
int p2 = m + 1;
while (p1 <= m && p2 <= r) {
help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= m) {
help[i++] = arr[p1++];
}
while (p2 <= r) {
help[i++] = arr[p2++];
}
for (i = 0; i < help.length; i++) {
arr[l + i] = help[i];
}
}
//for test
public static void printarr(int[] arr) {
for(int i = 0; i <= arr.length-1; i++) {
System.out.print(arr[i] + " ");
}
System.out.println(" ");
}
//for test
public static void main(String[] args) {
int[] res = {0,0,0,0,0,0,0,0,0,0};
int[] res1 = {0,0,0,0,0,0,0,0,0,0};
for(int i = 0; i < 10; i++) {
int ran = (int) (Math.random()*10 +8) - (int) (Math.random()*10 +2);
res[i] = ran;
res1[i] = ran;
}
Arrays.sort(res1);
printarr(res1);
Mergesort(res);
printarr(res);
if(Arrays.equals(res, res1))
System.out.println("Nice!");
else System.out.println("Fucking Fucked");
}
}
5、小和问题
package niuke;
import java.util.Arrays;
public class xiaheproblem {
public static int mergesort(int[] a) {
if(a.length <= 1)
return 0;
return mergesort(a, 0, a.length-1);
}
public static int mergesort(int[] a, int lindex, int rindex) {
if(rindex == lindex)
return 0;
int mid = (rindex + lindex)/2;
mergesort(a, lindex, mid);
mergesort(a, mid+1 , rindex);
return mergesort(a, lindex, mid) + merge(a, lindex, mid, rindex) + mergesort(a, mid+1 , rindex);
}
public static int merge(int[] arr, int l, int m, int r) {
int[] help = new int[r - l + 1];
int i = 0;
int p1 = l;
int p2 = m + 1;
int res = 0;
while (p1 <= m && p2 <= r) {
res += arr[p1] < arr[p2] ? (r - p2 + 1) * arr[p1] : 0;
help[i++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
}
while (p1 <= m) {
help[i++] = arr[p1++];
}
while (p2 <= r) {
help[i++] = arr[p2++];
}
for (i = 0; i < help.length; i++) {
arr[l + i] = help[i];
}
return res;
}
//for test
public static void main(String[] args) {
int re = 0;
int[] res = {1,2,3,4,5};
/*for(int i = 0; i < 5; i++) {
int ran = (int) (Math.random()*10 +8) - (int) (Math.random()*10 +2);
res[i] = ran;
System.out.print(ran + " ");
}*/
re = mergesort(res);
System.out.println(re);
}
}