2017.2.21 算法学习笔记

E01 课程简介以及算法分析

算法导论包括算法分析(Algorithm Analysis)与算法设计(Design)两部分。性能(Performance)是算法研究中的重点内容;鲁棒性、稳定性、模块化(Module)都是以性能保障作为前提的。

  • 实例1 插入排序(Inserting Sort/permutation)
#include "stdafx.h"
#include "iostream"
using namespace std;

int InsertionSort(int a[], int length) {
    int i = 0, j = 0;
    for (i = 1; i < length; i++) {
        int key = a[i];
        if (key < a[i - 1]) {
            for (j = i - 1; a[j] > key && j > -1; j--) {
                a[j + 1] = a[j];
            }
            a[j+1] = key;//这一步写成a[j] = key;就错了,因为每次循环结束后j已经-1,之后才进行位置判断
        }
    }
    cout << "排序后结果为:";
    for (int i = 0; i < length; i++) {
        cout << a[i] << ' ';
    }
    return 0;
}


int main()
{
    int a[100],length;
    cout << "输入数组长度:" << endl;
    cin >> length;
    cout << "输入测试数组:" << endl;
    for (int i = 0; i < length;i++) {
        cin >> a[i];
    }
    InsertionSort(a, length);
    return 0;
}

那么我们在分析算法时,究竟在分析什么?比较有用的一个指标是运行时间(Running time),但是比较算法的绝对运行时间时,往往会因为机器硬件的因素而使得结果差别很大,因此我们更加关注算法的相对速度(Relative Speed),也就是不同算法在同一机器上运行速度的相对快慢;与此同时算法的运行时间还和具体输入情况密切相关,举插入排序的例子而言,当输入数组为逆序时需要的步骤是最多的,相比正序或者基本有序的输入花费时间也就更多,当我们输入的数组中有10000个数时,排序所需要的时间自然也比排10个数来得更慢。
由前述分析我们可以得到影响运行时间的两个因素:输入情况、输入规模。在不同的输入下,运行时间各不相同;我们应当呈现给用户的是这个算法运行时间的上界(Upper bound)因为这是性能的一种“保证”。

分析算法时,有三种情况:最好、最坏、平均情况。最坏情况是指在所有输入情况下运行时间最长的那个,最好情况同理,平均情况指的是算法运行时间的一个加权平均值,权重依据是这种输入出现的概率,所以我们需要知道针对这一算法不同的输入的一个概率分布(而在实际中通常假设所有输入时等可能出现的)。
为了分析算法,我们引入了渐进分析(asymptotic analysis)的方法,这是一种工程学的观点,这种观点使得我们能够忽略机器因素,并且它更加关注于运行时间随规模的增长情况。

定义 渐进符号θ 运算符作用使得常数因子、低阶项被忽略,例如θ(3n^3+90n^2-55)=θ(n^3) 渐进符号代表了一种变化的趋势,也就是当n足够大时,Theata(n^3)>Theata(n^2)是一定会成立的

定义了渐进符号以后,就可以分析插入排序的运行时间,结果为Theata(n^2)
- 实例2 归并排序Merge Sort
伪代码描述:
[1] If n = 1, done.
[2] If n != 1, recursively sort A[1 ··· [n/2] ] and A[ [n/2]+1 ··· n ]
[3] Merge the array in step [2]

运用渐进分析的方法可以得到算法运行时间为Theta(n·logn)。此处需要用到递归树

你可能感兴趣的:(算法导论,算法学习笔记)