数据结构与算法--算法

数据结构 - 算法定义

算法就是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每个指令表示一个或多个操作

数据结构 - 算法特性
  • 输入输出
  • 有穷性
  • 确定性
  • 可行性
数据结构 - 算法设计要求
  • 正确性
  • 可读性
  • 健壮性
  • 时间效率高和储存量低
数据结构 - 算法比较

实现程序:求得1+2+3+......+100结果的程序?

第一种:
int sum,n;
n = 100;
sum = 0;
for (int i=0; i<=n; i++) {
    sum += I;
}
printf("%d",sum)
第二种:
int sum = 0,n=100;
sum = (1+n)*n/2;
printf("%d",sum);
  • 使用不同算法,解决同一个问题,效率可能相差非常大
    - 比如:求第n个斐波那契数(fibonacci number)
    0 1 1 2 3 5 8 13 ... 前两个数相加的和
/*
 * 0 1 1 2 3 5 8 13 ...斐波那契数   
 * */
public static int fib1(int n) {
    if (n<=1) return n;
    return fib1(n-1) + fib1(n-2);
}

/*
 * 0 1 2 3 4 5 ... n
 * 0 1 1 2 3 5 8 13 ...斐波那契数    O(n)
 * */ 
public static int fib2(int n) {
    if (n<=1) return n;
    int first = 0;
    int second = 1;
    for(int i=0;i
  • 如何评判一个算法的好坏
//计算1+2+3+...+n的和
public static int sum1(int n) {
    int result = 0;
    for (int i = 1; i <= n; i++) {
        result += I;
    }
    return result;
}
//计算1+2+3+...+n的和
public static int sum2(int n) {
    return (1+n)*n/2;
}

1、如果单从执行效率上进行评估,可以比较不同算法对同一组输入的执行处理时间,这种方案叫做事后统计法,但是有明显的缺点:<1>执行时间严重依赖硬件以及运行时各种不确定的环境因素;<2>必须编写相应的测算代码;<3>测试数据的选择比较难保证公正性
2、一般从以下维度来评估算法的优劣
- 正确性、可读性、健壮性(对不合理输入的反应能力和处理能力)
- 时间复杂度(time complexity):估算程序指令的执行次数(执行时间)
- 空间复杂度(space complexity):估算所需占用的存储空间
更多关注的一般是时间复杂度

数据结构 - 常见的时间复杂度
时间复杂度:
  1. 算法输入时间
  2. 编译可执行代码
  3. 执行指令
  4. 执行重复的指令
时间复杂度术语:
  1. 常数阶
  2. 线性阶
  3. 平方阶
  4. 对数阶
  5. 立方阶
  6. nlog阶
  7. 指数阶(不考虑)O(2^n)或者O(n!)除非是非常小的n,否则会造成噩梦般的时间消耗。这是一种不切实际的算法时间复杂度,一般不考虑
  • 大O表示法(Big O)
    1、一般用大O表示法来描述复杂度,它表示的是数据规模n对应的复杂度
    2、忽略常数、系数、低阶
    3、对数阶的细节:对数阶一般省略底数,log2(n) = log2(9) * log9(n),所以log2(n)、log9(n)统称为logn
9 >> O(1)
2n+3 >> O(n)
n^2 + 2n + 6 >> O(n^2)
4n^3 + 3n^2 + 22n + 100 >> O(n^3)
写法上,n³ = n^3

4、注意:大O表示法仅仅是一种粗略的分析模型,是一种估算,能短时间内了解一个算法的执行效率

public static void test1(int n) {
    //1
    if (n>10) {
        System.out.println("n>10");
    }else if (n>5) {
        System.out.println("n>5");
    }else {
        System.out.println("n<=5");
    }
    //1+4+4+4(i=0,1次;i++,4次;i<4,4次;打印4次)
    for (int i = 0; i < 4; i++) {
        System.out.println("test");
    }
    //14 时间复杂度 O(1)
        //空间复杂度O(1)
}
public static void test2(int n) {
    //1+3n 时间复杂度 O(n)
       //空间复杂度O(1)
    for (int i = 0; i < n; i++) {
        System.out.println("test");
    }
}
public static void test3(int n) {
    //1+2n+n*(1+3n) = 3n^2+3n+1  O(n^2)
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            System.out.println("test");
        }
    }
}
public static void test4(int n) {
    //1+2n+n*(1+15+15+15) = 48n+1 O(n)
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < 15; j++) {
            System.out.println("test");
        }
    }
}
public static void test5(int n) {
    //执行次数 = log2(n) O(logn)
    while ((n = n / 2) > 0) {
        System.out.println("test");
    }
}
public static void test6(int n) {
    //执行次数 = log5(n)  O(logn)
    while ((n = n / 5) > 0) {
        System.out.println("test");
    }
}
public static void test7(int n) {
    //n = 1*2*2*2...
    //执行次数 = 1 + log2(n) + log2(n) + log2(n)*(1+3n) = 1+3*log2(n)+3*nlog2(n)
    //O(nlogn)
    for (int i = 1; i < n; i += i) {//i+= i等价于i = I*2,
        //1 + 3n 
        for (int j = 0; j < n; j++) {
            System.out.println("test");
        }
    }
}
  • 可以借助函数生成工具对比复杂度的大小:函数图像绘制工具
数据结构 - 空间复杂度

算法的空间复杂度通过计算算法所需的存储空间实现,算法空间复杂度的计算公式记做:S(n) = n(f(n)),其中,n为问题的规模,f(n)为语句关于n所占存储空间的函数

数据结构 - 程序空间计算因素:

1.寄存本身的指令
2.常数
3.变量
4.输入
5.对数据进行操作的辅助空间

在考量算法的空间复杂度,主要考虑算法执行时所需要的辅助空间。

 问题:数组逆序,将一维数组a中的n个数逆序存放在原数组中。

void exangeArr(){
    int n = 10;
    int a[10] = {1,2,3,4,5,6,7,8,9,10};
    //算法实现(1) O(1)
    int temp;
    for (int i=0; i

fib函数(斐波那契数列)的时间复杂度分析
第一种递归算法:


1 + 2 + 4 + 8 = 20+21+22+23 = 2^4-1 = 2^(n-1)-1 = 0.5*2^n。
所以复杂度是O(2^n).
第二种算法 : O(n)

算法的优化方向
  • 用尽量少的存储空间
  • 用尽量少的执行步骤(执行时间)
  • 根据情况,可以空间换时间或者时间换空间
多个数据规模的情况
O(n+k)
public static void test(int n,int k) {
    for (int i = 0; i < n; i ++) {
        System.out.println("test");
    }
    for (int i = 0; i < k; i ++) {
        System.out.println("test");
    }
}
leetcode
  • 一个用于练习算法的好网站
    leetcode英文版
    leetcode中文版

你可能感兴趣的:(数据结构与算法--算法)