如何评价一个算法的好坏?

一般从以下维度来评估算法的好坏:

  • 正确性、可读性、健壮性(对不合理输入的反应能力和处理能力)
  • 时间复杂度(time complexity):估算程序指令的执行次数(执行时间)
  • 空间复杂度(space complexity):估算所需要占用的存储空间

    复杂度:一个关于输入数据量n的函数

  • 时间复杂度 — 昂贵

    • 与代码的结构设计有紧密联系
    • 一个顺序结构的代码,时间复杂度是 O(1),即任务与算例个数n 无关
  • 空间复杂度 — 廉价

    • 与数据结构设计有关

      大O表示法(Big O Notation)

  • 一般用大O表示法来描述复杂度,它表示的是数据规模n对应的复杂度

  • 忽略常数、系数、低阶
  • 9 >> O(1)
  • 2n+3 >> O(n)
  • n^2 +2n+3 >> O(n^2)
  • 4n^3 +7n^2 +3n+2 >> O(n^2)
  • 注意:大O标识法仅仅是一种粗略的分析模型,是一种估算,能帮助我们短时间内了解一个算法的执行效率
  • 对数阶的细节
    • 对数阶一般省略底数
    • logn = log9 + logn
    • 所以 logn、logn 统称为 log n

**

常见复杂度

执行次数 复杂度 非正式语
12 O(1) 常数阶
2n+3 O(n) 线性阶
4n^2 +2n+3 O(n^2) 平方阶
4logn+25 O(log n) 对数阶
3n+2nlogn+15 O(nlogn) nlogn阶
4n^3 +7n^2 +3n+2 O(n^3) 立方阶
2^n O(2^n) 指数阶

O(1) < O(log n) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n)
**

  1. public static void test1(int n) {
  2. //1
  3. if (n > 10) {
  4. System.out.println("n > 10");
  5. } else if (n > 5) { // 2
  6. System.out.println("n > 5");
  7. } else {
  8. System.out.println("n <= 5");
  9. }
  10. // 1 + 4+4+4
  11. for (int i = 0; i < 4; i++) {
  12. System.out.println("test");
  13. }
  14. //14 >> O(1)
  15. }
  16. public static void test2(int n) {
  17. // 1+ n +n + n=1+3n >> O(n)
  18. for (int i = 0; i < n; i++) {
  19. System.out.println("test");
  20. }
  21. }
  22. public static void test3(int n) {
  23. // 1+ n +n + n * (1+3n)
  24. // 1+2n + n +3n^2
  25. // 1+ 3n+ 3n^2 >> O(n^2)
  26. for (int i = 0; i < n; i++) {
  27. //1+3n
  28. for (int j = 0; j < n; j++) {
  29. System.out.println("test");
  30. }
  31. }
  32. }
  33. public static void test4(int n) {
  34. // 1 + n + n + n * (1+15+15+15)
  35. // 1+2n +46n
  36. // 1+48n >> O(n)
  37. for (int i = 0; i < n; i++) {
  38. for (int j = 0; j < 15; j++) {
  39. System.out.println("test");
  40. }
  41. }
  42. }
  43. //O(log n)
  44. public static void test5(int n) {
  45. // n = 8 >> 8/2=4 >> 4/2=2 >>2/2= 1 >> 0
  46. // 2^3 = 8
  47. //a ^ x = n >> x =log a N >> 3 = log 2 8 >> O(log 2 n) >> O(log n)
  48. while ((n = n / 2) > 0) {
  49. System.out.println("test");
  50. }
  51. }
  52. public static void test6(int n) {
  53. // O(log 5 n) >> O(log n)
  54. while ((n = n / 5) > 0) {
  55. System.out.println("test");
  56. }
  57. }
  58. public static void test7(int n) {
  59. // i+=i <==> i=i+i <==> i = i * 2
  60. // n=8 i=1 <8 , i = 1*2
  61. // n=8 i=2 <8 , i = 2*2
  62. // n=8 i=4 <8 , i = 4*2
  63. // >> log 2 8
  64. // 1 + log n + log n + (log n * (1 + 3n))
  65. // 1+ log n + logn + logn +3nlogn
  66. // >> O(nlogn)
  67. for (int i = 1; i < n; i += i) {
  68. // 1 + 3n
  69. for (int j = 0; j < n; j++) {
  70. System.out.println("test");
  71. }
  72. }
  73. }
  74. //O(n)
  75. public static void test10(int n) {
  76. int a = 10;
  77. int b = 20;
  78. int c = a + b;
  79. int[] array = new int[n];
  80. for (int i = 0; i < array.length; i++) {
  81. System.out.println(array[i] + c);
  82. }
  83. }

image.png
image.pngimage.png
image.png
image.png
image.png