计算机算法设计与分析(1-6章 复习笔记)

简介: 计算机算法设计与分析(1-6章 复习笔记)

计算机算法设计与分析

最近发现一些刷题的网站,牛客、力扣,很适合用来熟悉算法和语言知识点。

第1章 算法概述

1.1 算法与程序

算法 是解决问题的一种方法或一个过程。

    严格地说,算法是由若干条指令组成的有穷序列,且满足下述4条性质。

  1. 输入
  2. 输出:至少产生一个量作为输出。
  3. 确定性:每条指令清晰、无歧义。
  4. 有限性:执行次数、时间有限

程序和算法不同。程序不一定满足上述4条性质。

1.2 算法复杂性分析

最坏时间复杂度:O;时间上界;

1.3 NP完全性理论

可在多项式时间内求解的判断问题构成    P类问题。

第2章 递归与分治策略

 分治法的思想:将一个难以直接解决的大问题分解为一些规模较小的相同问题,以便各个击破,分而治之。

2.1 递归的概念

直接或间接调用自身的算法称为递归算法。

【例2-1】阶乘函数。

阶乘函数可递归的定义为:

n!  = 1            ,n=0

   = n(n-1)!   ,  n>0

递归式的第一式给出了这个函数的 初始值,是非递归定义的(直接给出)。每个递归函数都必须有非递归定义的初始值,否则会一直递归下去。

递归式的第二式用较小的自变量的函数值来表示较大自变量的函数值的方法来定义n的阶乘。

用代码表示:

int factorial(int n){
 
    if (n==0)
 
        return 1;
 
    else
 
        return n*factorial(n-1);
 
}

【例2-6】Hanoi塔问题

问题略。

可用递归方法解决:

当n=1时,只要将当前盘子从当前位置塔a放在目标塔b即可。

当n>1时,需要利用塔c作为辅助塔,将n-1个圆盘移动到c上,然后将剩下的最大圆盘移动到b上。即n个圆盘的问题变成两次n-1个圆盘的问题。

用代码表示:

//4个参数依次是剩余数量,起点,终点,中间点
 
void hanoi(int n, char a, char b, char c){
 
    if (n==1)
 
        move(a,b);
 
    else
 
    {
 
       hanoi(n-1,a,c,b);
 
       move(a,b);
 
       hanoi(n-1,c,b,a);
 
    }
 
       
 
}
 
void move(char begin,char end){
 
cout<<begin<<"--->"<<end<<"\n";
 
}


2.2 分治法的基本思想

分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,子问题之间相互独立且与原问题类型相同。

2.3二分搜索技术

二分搜索是分治的典型例子。

给定已排好序(为了简便,设为升序排序)的n个元素a[0,n-1],要在其中找到一特定元素x。

如果用顺序搜索(从头开始依次往后比较),最坏情况需要n次比较;

分搜索采用分治策略,最坏情况用O(logn) 时间完成。

二分搜索的基本思想:将n个元素分成数量基本相同的两份,取a[n/2]与x比较,如果x 等于a[n/2],则找到,算法终止;如果x<a[n/2],则x较小,只要在数组a的左半部继续搜索;

如果x>a[n/2],则x较大,只要在数组a的右半边继续搜索。

/*二分搜索 */
 
template<class Type>
 
int BinarySearch(Type a[],const Type& x, int n){
 
    int left = 0;
 
    int right = n-1;
 
    while(left<=right)
 
    {
 
        int middle = (left+right)/2;
 
        if (x==a[middle])
 
            return middle;
 
        if (x>a[middle])
 
            left = middle+1;
 
        if (x<a[middle])
 
            right = middle-1;
 
    }
 
    return -1;
 
}
 
 
 
//递归形式
 
int  BinarySearch(int a[],int x,int left,int right){
 
    if(left>right)
 
        return -1;
 
    int middle = (left+right)/2;
 
    if (x==a[middle])
 
        return middle;
 
    if(x<a[middle])
 
        return BinarySearch(a,x,left,middle-1);
 
    if(x>a[middle])
 
        return BinarySearch(a,x,middle+1,right);
 
}

2.4 大整数的乘法

有二进制整数X和Y,要计算X * Y,

将X分成两份:A、B,

Y分解两份:C、D

XY = (A*2n/2 +B)(C*2n/2 +D)

=AC*2n +((A-B)(D-C)+AC+BD)* 2n/2 +BD  //利用数学变形,减少乘法次数

2.5 Strassen矩阵乘法

(直接分解再乘并不能减少乘法次数,通过一些变形增加加减法次数,减少乘法次数)。

2.7 合并序。

用分治策略对N个元素进行排序。

基本思想:将待排序的n个元素分成大小大致相同的两个子集,分别对两个子集进行排序,然后再合并两个子集。

template<class Type>
 
void MergeSort(Type a[],Type b[], int left, int right) {
 
    if (left < right) {
 
        int i = (left + right) / 2;
 
        MergeSort(a, b,left, i);
 
        MergeSort(a, b,i + 1, right);
 
        Merge(a, b, left, i, right); //合并到b数组
 
        Copy(a, b, left, right);   //复制回a数组
 
    }
 
 
 
template<class Type>
 
void Merge(Type c[], Type d[], int l, int m, int r) {  //合并c[l:m]和c[m+1:r]到d[l:r]
 
    int i = l, j = m + 1;
 
    int pos = l;
 
    while ((i <= m) && (j <= r)) {
 
        if (c[i] <= c[j])
 
            d[pos++] = c[i++];
 
        else
 
            d[pos++] = c[j++];
 
        if (i > m) {    //第1个数组放完了,直接把第2个数组剩下的放到d
 
            for (int q = j; q <= r; q++)
 
                d[pos++] = c[q];
 
        }
 
        if (j > r) {      //第2个数组放完了,直接把第1个数组剩下的放到d
 
            for (int q = i; q <= m; q++)
 
                d[pos++] = c[q];
 
        }
 
    }
 
}
 
 
 
template<class Type>
 
void Copy(Type a[], Type b[], int left, int right) {
 
    for (int i = left; i <= right; i++)
 
        a[i] = b[i];
 
}

2.8 快速排序

对于数组a[p:r]按三个 步骤排序:

1. 分解(Divide):以a[p]为基准元素,a[p:r]分解为3段:a[p:q-1].a[q]]和a[q+1:r]

使得a[p:q-1]中的元素都<=a[q] , a[q+1:r]>=a[q],下标q在划分过程中确定。

2.递归求解(Conquer):使用递归对a[p:q-1]和a[q+1:r]进行排序。

3.合并(Merge):a[p:q-1]和a[q+1:r]排序好后,不需要进行操作就已经排好序了。

template<class Type>
 
void QuickSort(Type a[],int p,int r){
 
    if(p<r){
 
        int q = Partition(a,p,r);
 
        QuickSort(a,p,q-1);
 
        QuickSort(a,q+1,r);
 
    }
 
}
 
 
 
template<class Type>
 
int Partition(Type a[],int p, int r){
 
    int i=p+1, j =r;
 
    Type x = a[p];
 
    while(true){
 
        while(a[i]<x && i<r)   //直到找到a[i]>=x
 
            i++;
 
        while(a[j]>x)           //直到找到a[j]<=x
 
            j--;
 
        if(i>=j)
 
            break;
 
        swap(a[i],a[j]);    //交换a[i],a[j],使得左边都小于x,右边>x
 
    }
 
   swap(a[p],a[j]);
 
    return j;
 
}
相关文章
|
1天前
|
缓存 算法 搜索推荐
Java中的算法优化与复杂度分析
在Java开发中,理解和优化算法的时间复杂度和空间复杂度是提升程序性能的关键。通过合理选择数据结构、避免重复计算、应用分治法等策略,可以显著提高算法效率。在实际开发中,应该根据具体需求和场景,选择合适的优化方法,从而编写出高效、可靠的代码。
15 6
|
27天前
|
人工智能 并行计算 算法
量子计算算法:超越经典计算机的边界
量子计算基于量子力学原理,利用量子位、量子叠加和量子纠缠等特性,实现并行计算和高效处理复杂问题。核心算法如Shor算法和Grover算法展示了量子计算在大数分解和搜索问题上的优势。尽管面临量子位稳定性和规模化等挑战,量子计算在化学模拟、优化问题和人工智能等领域展现出巨大潜力,预示着未来的广泛应用前景。
|
25天前
|
并行计算 算法 测试技术
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面
C语言因高效灵活被广泛应用于软件开发。本文探讨了优化C语言程序性能的策略,涵盖算法优化、代码结构优化、内存管理优化、编译器优化、数据结构优化、并行计算优化及性能测试与分析七个方面,旨在通过综合策略提升程序性能,满足实际需求。
56 1
|
2月前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。
|
2月前
|
机器学习/深度学习 人工智能 算法
量子计算算法:超越经典计算机的边界
【10月更文挑战第30天】量子计算基于量子力学原理,通过量子比特和量子门实现超越经典计算机的计算能力。本文探讨量子计算的基本原理、核心算法及其在密码学、化学、优化问题和机器学习等领域的应用前景,并讨论当前面临的挑战与未来发展方向。
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-19
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-19
63 3
|
2月前
|
存储 人工智能 算法
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-13(上)
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-13(上)
45 2
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-16
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-16
42 1
|
2月前
|
机器学习/深度学习 人工智能 算法
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-15
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-15
64 1
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-14
计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-10-14
53 1