《算法导论》个人笔记(一)

来源:互联网 发布:淘宝设置优惠券要钱吗 编辑:程序博客网 时间:2024/05/22 09:47
今天的笔记是第一部分:基础知识中的第1、2章内容。先来个概述,第一章主要介绍算法是什么,算法在计算中能起到什么作用。第二章主要介绍算法基础,讲了一个插入排序算法,同时介绍了如何分析算法的复杂度,还引入了分治法的思想,归并排序算法。另,包含一些练习题。
一、算法
  1. 算法是什么
        算法就是任何定义良好的计算过程,它取一个或一组值作为输入,并产生出一个或一组值作为输出。也就是说,算法就是一系列的计算过程,用来将输入的数据转换成输出结果。
        例如:我们需要把一个数列按照非递减排序。下面是关于排序问题的形式定义。
        输入:n个数的一个序列{a1,a2,a3,a4,…,an}。
      输出:输入序列的一个排列{a1’,a2’,a3’,a4’,…,an’},满足a1’<= a2’ <= a3’ … <= an’。
  2. 算法的应用
  3. 以上咱们使用算法解决排序问题,但是算法实际应用无处不在。例如:
    • 分析数据库中存储的人类基因工程中30亿个化学基对的序列
    • 管理和处理互联网上的海量数据,访问与检索大量信息
    • 电子商务对个人订单信息保密,核心技术是公钥密码和数字签名
二、算法基础
1、插入排序法
  • 插入排序是一个对少量元素进行排序的有效算法。
    我们将其伪代码过程命名为INSERTION-SORT,它的参数是一个数组A[1 .. n],包含了n个待排数字。
    (在伪代码中,A中元素的个数n用A.length来表示)
    算法思想:每趟将一个元素,按照其中元素的大小插入到它前面已经排序的子序列中,依此重复,直到插入全部元素。
        **INSERTION-SORT(A)**    for j = 2 to A.length        key = A[j]        // Insert A[j] into the sorted sequence A[1 .. j - 1]        i = j - 1        while i > 0 and A[i] > key            A[i + 1] = A[i]            i = i - 1        A[i + 1] = key
  • 插入排序算法的简单Java实现
        /**     * 插入排序     *     * @param array     */    public static void insertionSort(int[] array) {        int key, j;        for (int i = 1; i < array.length; i++) {            key = array[i];            j = i - 1;            while (j >= 0 && array[j] > key) {                array[j + 1] = array[j];                j--;            }            array[j + 1] = key;        }    }
  • 算法分析

        算法分析是指对一个算法所需要的资源进行预测。内存,通信带宽或计算机硬件等资源偶尔会是我们主要关心的,但通常,资源是指我们希望度量的是计算时间。
        我们就不把插入排序算法的分析过程一一贴出来了,插入排序算法的时间复杂度是T(n)=O(n*n)。

2、分治思想
  • 将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些子问题。然后再合并这些子问题的解来建立原问题的解。
    分治模式在每层l递归时都有三个步骤:
    • 分解原问题为若干子问题,这些子问题是原问题的规模较小的实例。
    • 解决这些子问题,递归地求解各个子问题。然而,若子问题的规模足够小,则直接求解。
    • 合并这些子问题的解成原问题的解。
  • 归并排序算法
    归并排序算法完全遵循分治模式。 直观上操作如下:
    • 分解:将 n 个元素分成各含 n / 2个元素的子序列;
    • 解决:用归并排序法对两个子序列递归地排序;
    • 合并:合并两个已排序的子序列以得到排序结果。
        对子序列排序时,其长度为1时递归”开始回升”。在这种情况下不要做任何工作,因为长度为1的每个序列都已排好序。归并排序的关键步骤在于合并两个已排序的子序列。
        这里引入一个辅助过程MERGE(A, p, q, r),其中A为数组,p,q和r都是下标,有p <= q < r。该过程假设子数组A[p .. q]和A[q+1 .. r]都已排好序,并将它们合并成一个已排好序的子数组代替当前子数组A[p .. r]。
  • 归并排序算法的实现
    合并步骤:
    MERGE(A, p, q, r)   n1 = q - p + 1   n2 = r - q   let L[1 .. n1 + 1] and R[1 .. n2 + 1] be new arrays   for i = 1 to n1       L[i] = A[p + i - 1]   for j = 1 to n2       R[j] = A[q + j]   L[n1 + 1] = MAX   R[n2 + 1] = MAX   i = 1   j = 1   for k = p to r       if L[i] <= R[j]           A[k] = L[i]           i = i + 1       else           A[k] = R[j]           j = j + 1
    排序步骤:
        MERGE(A, p, q, r)    n1 = q - p + 1    n2 = r - q    let L[1 .. n1 + 1] and R[1 .. n2 + 1] be new arrays    for i = 1 to n1        L[i] = A[p + i - 1]    for j = 1 to n2        R[j] = A[q + j]    L[n1 + 1] = MAX    R[n2 + 1] = MAX    i = 1    j = 1    for k = p to r        if L[i] <= R[j]            A[k] = L[i]            i = i + 1        else             A[k] = R[j]            j = j + 1
  • 归并排序算法Java实现
        /**    * 归并排序    *    * @param array    */    public static void mergeSort(int[] array) {        mergeSort(array, 0, array.length - 1);    }    private static void mergeSort(int[] array, int p, int r) {        int q;        if (p < r) {            q = (p + r) >> 1;            mergeSort(array, p, q);            mergeSort(array, q + 1, r);            merge(array, p, q, r);        }    }    private static void merge(int[] array, int p, int q, int r) {        int lLen = q - p + 1;        int rLen = r - q;        int[] left = new int[lLen + 1];        int[] right = new int[rLen + 1];        int i, j;        for (i = 0; i < lLen; i++)            left[i] = array[p + i];        for (j = 0; j < rLen; j++)            right[j] = array[q + j + 1];        left[i] = Integer.MAX_VALUE;        right[j] = Integer.MAX_VALUE;        i = j = 0;        for (int k = p; k <= r; k++) {            if (left[i] <= right[j])                array[k] = left[i++];            else                array[k] = right[j++];        }    }
习题
  1. 插入排序改写成递归过程
    INSERTION-SORT-RECURSIVE(A, p)    if p > 1        key = A[p]        p = p - 1        INSERTION-SORT-RECURSIVE(A, p)        INSERTION-ELEMENT(A, p, key)INSERTION-ELEMENT(A, p, key)    while p > 0 and A[p] > key        A[p + 1] = A[p]        p = p - 1    A[p + 1] = key
  2. 二分查找伪码
    **BINARY-SEARCH(A, v)**    front = 1    end = A.length    while front < end        middle = (front + end) / 2        if A[middle] < v            front = middle + 1        else if A[middle] > v            end = middle - 1        else            return middle    return -1
  3. 设计算法:查找集合S中是否存在两个元素和等于x的元素。
    思路:先排序,后查找
    **CHECK-SUM(S, x)**    A = MERGE-SORT(S)    for i = 1 to A.length        v = x - A[i]        if BINARY-SEARCH(A, v) > 0            return true    return false
感谢大家花时间阅读本人博客,在接下来每周会更新一篇算法导论的算法设计博文。当中有什么问题还请大家指正,相互学习,相互促进!

原创粉丝点击