深入浅出的算法设计与分析技巧解读(软件设计师笔记)

news2025/2/24 11:30:29

😀前言
在计算机科学的庞大体系中,算法始终占据着核心的地位,充当着解决问题的“钥匙”。本章主要深入探讨了算法设计与分析这一主题,旨在通过具体的问题解析和代码实现,引导读者深入理解各种经典算法的设计原理和应用策略。我们将探讨如何量化算法的效率和效果,并通过多种算法策略(如回溯法、分治法、动态规划法和贪心法)的探讨,展示了算法如何在不同的问题领域中发挥其关键作用。
本章的核心不仅是在于算法本身的分析和实现,更在于培养读者独立分析问题、选择或设计算法的能力。我们将通过多个问题实例,展示了如何通过不同算法策略,从不同的角度分析和解决问题。

🏠个人主页:尘觉主页
在这里插入图片描述

🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力😉😉

在csdn获奖荣誉: 🏆csdn城市之星2名
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 💓Java全栈群星计划top前5
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 🤗 端午大礼包获得者
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 🥰阿里云专家博主
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 😉亚马逊DyamoDB结营

💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看🥰
如果文章有什么需要改进的地方还请大佬不吝赐教 先在次感谢啦😊

文章目录

    • 第八章 算法设计与分析
        • 时间复杂度
        • 空间复杂度
        • 回溯法
          • n皇后问题
        • 分治法
          • 归并排序算法
          • 最大字段和问题
        • 动态规划法
          • 0-1 背包问题
          • 矩阵连乘问题
        • 贪心法
          • 部分背包问题
    • 😄总结

第八章 算法设计与分析

时间复杂度

算法时间复杂度以算法中基本操作重复执行的次数(简称为频度)作为算法的时间度量。一般不必要精确计算出算法的时间复杂度,只要大致计算出相应的数量级即可,如O(1)、O(㏒₂n)、O(n)或O(n²)等。


递归式时间复杂度:递归的次数 x 每次递归的时间复杂度

主方法。主方法也称为主定理,给出了求解以下形式的递归式的快速方法。

空间复杂度

非递归:O(1) O(n) O(n²)

回溯法
n皇后问题

#include<stdio.h>
#include"stdlib.h"

int Place(int *Column,int index){
    int i;
    for(i=1;i<index;i++){
        int Column_differ = abs(Column[index] - Column[i]);
        int Row_differ = abs(index - i);
        if(Column[i] == Column[index] || Column_differ == Row_differ)
            return 0;
    }
    return 1;
}

void N_Queue(int n){
    int Column_Num[n+1];
    int index = 1;
    int i;

    int answer_num = 0;
    for(i=1;i<=n;i++)
        Column_Num[i] = 0;
    while(index>0){
        Column_Num[index]++;
        while(Column_Num[index] <= n && !Place(Column_Num,index))
            Column_Num[index]++;
        if(Column_Num[index] <=n){
            if (index == n) {
                answer_num++;
            
                printf("方案%d:",answer_num);

                for(i=1;i<= n;i++){
                    printf("%d ",Column_Num[i]);
                }
                printf("\n");
            }else {
                index++;
                Column_Num[index]=0; 
            }
        }else {
            index--;
        }
    }
}

int main(){
    N_Queue(6);
    return 0;
}
分治法

递归有两个基本要素:

  • 边界条件,即确定递归到何时终止,也称为递归出口
  • 递归模式,即大问题是如何分解为小问题的,也称为递归体

分支算法在每一层递归上都有 3 个步骤:

  1. 分解。将原问题分解成一系列子问题。
  2. 求解。递归地求解各子问题。若子问题足够小,则直接求解。
  3. 合并。将子问题的解合并成原问题的解。
归并排序算法
#include<stdio.h>

#define INT_MAX 2147483647
/**
 * 归并排序
**/
void Merge(int A[],int p,int q,int r){
    int n1 = q - p + 1,n2 = r -q,i,j,k;
    int L[50],R[50];
    for(i=0;i<n1;i++)
        L[i] = A[p+i];
    for(j=0;j<n2;j++)
        R[j] = A[q+j+1];
    L[n1] = INT_MAX;
    R[n2] = INT_MAX;
    i=0;
    j=0;
    for(k=p;k<r+1;k++){
        if(L[i] < R[j]){
            A[k] = L[i];
            i++;
        }else{
            A[k]=R[j];
            j++;
        }
    }
}

void MergeSort(int A[],int p,int r){
    int q;
    if(p < r){
        q = (p+r) / 2;
        MergeSort(A, p, q);
        MergeSort(A, q+1, r);
        Merge(A, p, q,r);
    }
}



int main(){
    int A[] = {4,1,3,6,7,5,2,9};
    MergeSort(A, 0, 7);

    int i;
    for (i = 0; i<8; i++) {
        printf("%d ",A[i]);
    }
    printf("\n");
    return 0;
}

最大字段和问题

#include<stdio.h>
#include<stdlib.h>

int MaxSubSum(int * Array,int left,int right){
    int sum = 0;
    int i;
    if(left == right){ /*分解到单个整数,不可继续分解*/
        if(Array[left] > 0)
            sum = Array[left];
        else
            sum = 0;
    }else{
        /*从 left 和 right 的中间分解数组*/
        int center = (left + right)/2; /*划分的位置*/
        int leftsum = MaxSubSum(Array, left, center);
        int rightsum = MaxSubSum(Array, center+1, right);
        /*计算包括 center 的最大值,判断是情形1、情形2还是情形3*/
        int s1 = 0;
        int lefts = 0;
        for(i = center;i >= left;i--){
            lefts = lefts + Array[i];
            if(lefts > s1)
                s1 = lefts;
        }
        int s2 = 0;
        int rights = 0;
        for(i = center + 1;i<= right;i++){
            rights = rights + Array[i];
            if(rights > s2)
                s2 = rights;
        }
        sum = s1 + s2;

        /*情形1*/
        if (sum < leftsum) {
            sum = leftsum;
        }
        /*情形2*/
        if(sum < rightsum){
            sum = rightsum;
        }
    }
         return sum;
}

int main(){
    int *Array = (int *)malloc(6*sizeof(int));
    Array[0] = -2;
    Array[1] = 11;
    Array[2] = -4;
    Array[3] = 13;
    Array[4] = -5;
    Array[5] = -2;

    int result = MaxSubSum(Array, 0, 5);
    printf("%d\n",result);

    return 0;
}

动态规划法
0-1 背包问题
#include<stdio.h>

#define N 4 // 物品数量
#define W 5 // 背包容量

int max(int a,int b){
    return a > b ? a : b;
}

int main(){
    int v[] = {0,2,4,5,6}; // 物品价值数组
    int w[] = {0,1,2,3,4}; // 物品重量数组

    int f[N + 1][W + 1] = {}; // 子问题解数组

    int i,j;
    for(i=1;i<=N;i++){
        for(j=1;j<=W;j++){
            if(j >= w[i]){ // 选第 i 个物品的前提条件
                // 等于不选第 i 个物品 和 选第 i 个物品 两者的较大值
                f[i][j] = max(f[i-1][j],f[i-1][j-w[i]] + v[i]);
            }else{ // 不选第 i 个物品
                f[i][j] = f[i - 1][j]; // 等于从前 i-1 个物品中选,背包容量为 j 时的最大价值    
            }
        }
    }

    printf("%d\n",f[N][W]);

    return 0;
}

时间复杂度:O(N*W) N:物品数量 W:背包容量

矩阵连乘问题
  • 时间复杂度:O(n³)
  • 空间复杂度O(n²)
贪心法
部分背包问题
#include<stdio.h>

#define N 5     // 物品数量
#define W 100   // 背包容量

// 显示物品价值、重量、单位重量价值数组
void show(int v[],int w[],double vw[]){
    int i;

    printf("物品价值数组:");
    for(i = 1;i<=N;i++) printf("%d ",v[i]);
    printf("\n");

    printf("物品重量数组:");
    for(i = 1;i<=N;i++) printf("%d ",w[i]);
    printf("\n");

    printf("物品单位重量价值数组:");
    for(i = 1;i<=N;i++) printf("%0.1lf ",vw[i]);
    printf("\n");



}

double Max_Value(int v[],int w[],double vw[]){
    double result = 0.0;

    int i;
    int w_temp = W;
    for(i=1;i<=N;i++){
        if(w_temp >= w[i]){
            result = result + v[i];

            w_temp = w_temp - w[i];
        }else{
            break;
        }
    }

    if(w_temp > 0 && i<=N){
        result = result + w_temp * vw[i];
    }
    return result;
}

int main(){

    int v[] = {0,65,20,30,60,40};   // 物品价值数组
    int w[] = {0,30,10,20,50,40};   // 物品重量数组

    double vw[N + 1]; // 物品单位重量价值数组

    int i;
    // 初始化 物品单位重量价值数组
    for(i = 1;i<=N;i++) vw[i] = (double) v[i] / w[i];

    show(v, w, vw);

    double result =Max_Value(v, w, vw);
    printf("\nreslut %.1lf\n",result);

    return 0;
}

😄总结

经过对算法设计与分析的深入探讨,我们对各类算法及其在不同问题场景中的应用有了更加深入的理解。
本章囊括了从基本的时间、空间复杂度分析,到复杂的递归、动态规划和贪心算法的设计与应用。我们通过代码示例,深入浅出的探讨了每种算法的优缺点和适用场景,希望能够为读者在未来的学习和工作中解决实际问题提供指导。

在今后的实际应用中,算法的选择和设计不应僵化地依赖于理论和模型,而应充分考虑实际问题的特性,发挥创新和批判性思维,不断拓宽问题解决的多元路径。我们期待读者在理解和掌握了本章内容的基础上,能够在未来的学习和研究中,更加灵活和深刻地应用算法,解决更加复杂和多元的问题。

在算法的世界里,每一个问题都有它的解决之道。而找到最优、最适应的解决方案,需要我们不断的学习和实践。希望本章内容能为我们的算法学习之旅打下坚实的基础,使我们在解决问题的道路上更加从容和自信。

😁热门专栏推荐
想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

手写机制

微服务组件

spring_尘觉

springMVC

mybits

等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

🤔欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1058507.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ElasticSearch第四讲:ES详解:ElasticSearch和Kibana安装

ElasticSearch第四讲&#xff1a;ES详解&#xff1a;ElasticSearch和Kibana安装 本文是ElasticSearch第四讲&#xff1a;ElasticSearch和Kibana安装&#xff0c;主要介绍ElasticSearch和Kibana的安装。了解完ElasticSearch基础和Elastic Stack生态后&#xff0c;我们便可以开始…

力扣 -- 322. 零钱兑换(完全背包问题)

参考代码&#xff1a; 未优化代码&#xff1a; class Solution { public:int coinChange(vector<int>& coins, int amount) {int n coins.size();const int INF 0x3f3f3f3f;//多开一行&#xff0c;多开一列vector<vector<int>> dp(n 1, vector<i…

cadence - 解决orcad无响应的有效方法

文章目录 解决orcad无响应的有效方法概述笔记备注补充好像必须要在英文(美国)语言的主环境下运行才行补充 - orcad无响应的可能原因补充 - 英文模式也不好使补充 - orcad无响应的真实原因解决orcad无响应的有效方法END 解决orcad无响应的有效方法 概述 在画H7的飞达控制底板.…

复习C语言数组的用法

实验内容 1.1设计一个函数fun&#xff0c;功能是有N*N的矩阵&#xff0c;根据给定的m值&#xff0c;m<N,将每行元素中的值&#xff0c;均往右移m个位置&#xff0c;左边置0 #include<stdio.h> void fun(int (*a)[3],int m){int n,j,i,k,num;int p2;//右移位置列数nu…

Linux:minishell

目录 1.实现逻辑 2.代码及效果展示 1.打印字符串提示用户输入指令 2.父进程拆解指令 3.子进程执行指令,父进程等待结果 4.效果 3.实现过程中遇到的问题 1.打印字符串的时候不显示 2.多换了一行 3.cd路径无效 4.优化 1.ll指令 2.给文件或目录加上颜色 代码链接 模…

MySQL进阶 —— 超详细操作演示!!!(下)

MySQL进阶 —— 超详细操作演示&#xff01;&#xff01;&#xff01;&#xff08;下&#xff09; 五、锁5.1 概述5.2 全局锁5.3 表级锁5.4 行级锁 六、InnoDB 引擎6.1 逻辑存储结构6.2 架构6.3 事务原理6.4 MVCC 七、MySQL 管理7.1 系统数据库7.2 常用工具 MySQL— 基础语法大…

【管理运筹学】第 8 章 | 动态规划(5,设备更新问题)

系列文章 【管理运筹学】第 8 章 | 动态规划&#xff08;1&#xff0c;多阶段决策过程与动态规划基本概念&#xff09; 【管理运筹学】第 8 章 | 动态规划&#xff08;2&#xff0c;动态规划的基本思想与模型求解&#xff09; 【管理运筹学】第 8 章 | 动态规划&#xff08;3&…

Vscode 如何创建java项目,并添加包

创建java项目 添加包 先打开这个资源管理器中的javaProject&#xff0c;然后打开这个javaProject&#xff0c;点击里面的Reference Libraries,然后点击加号 选择要添加的包然后进行确认即可

C/C++学习 -- 分组密算法(3DES算法)

1. 3DES算法概述 3DES&#xff08;Triple Data Encryption Standard&#xff09;&#xff0c;又称为TDEA&#xff08;Triple Data Encryption Algorithm&#xff09;&#xff0c;是一种对称加密算法&#xff0c;是DES&#xff08;Data Encryption Standard&#xff09;的加强版…

k8s全栈-笔记6-Prometheus+Alertmanager构建监控系统

k8s全栈-笔记6-PrometheusAlertmanager构建监控系统 实验环境: Pormetheusgrafanaalertmanager安装在k8s集群,k8s环境如下 K8S集群角色IP主机名安装的组件控制节点(master)172.20.252.181k8s-master01apiserver,controller-manager,schedule,kubelet,etcd,kube-proxy,容器运…

vcruntime140.dll如何修复,快速修复vcruntime140.dll丢失的三种方法

vcruntime140.dll是Visual C 2015运行库的一个组件&#xff0c;它包含了许多运行时函数&#xff0c;用于支持各种程序的正常运行。当vcruntime140.dll文件丢失时&#xff0c;可能会导致一些程序无法正常运行。本文将详细介绍vcruntime140.dll的作用、丢失原因以及三种修复方法。…

STM32Cubemx新建F429基础工程

配置STM32CubeMX 配置KEY 配置USART1 配置RCC Project Manager Toolchain 选择 MDK-ARM Code Generator 配置如下 GENERATE CODE 即可 配置Keil5 魔术棒配置 – Target – 勾选 Use MicroLIB – Debug – Flash Download – 勾选Reset and Run 基础代码 /* Private incl…

linux——信号

✅<1>主页&#xff1a;&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;Linux——进程等待 ☂️<3>开发环境&#xff1a;Centos7 &#x1f4ac;<4>前言&#xff1a;生活中处处有信号&#xff0c;linux中也有很多信号&#xff0c;OS使…

算法强训:第三十四天

文章目录 收件人列表养兔子一、收件人列表OJ链接 本题思路:先接收到一个数字,代表接下来是多少组数据 ,逐个接收每个名字,如果名字中没有,或者 则直接输出,否则在改名字前后拼接"\""再输出,除最后一个名字外,每个名字之后都有一个", " ,该组用例…

(三)激光线扫描-中心线提取

光条纹中心提取算法是决定线结构光三维重建精度以及光条纹轮廓定位准确性的重要因素。 1. 光条的高斯分布 激光线条和打手电筒一样,中间最亮,越像周围延申,光强越弱,这个规则符合高斯分布,如下图。 2. 传统光条纹中心提取算法 传统的光条纹中心提取算法有 灰度重心法、…

pycharm中个人编程时常用到的快捷键

pycharm中个人编程时常用到的快捷键&#xff1a; 仅个人经验总结&#xff0c;不为其他&#xff01; 1.CTRLShiftAlt鼠标选择多个位置 可以同时在多个位置进行编辑同样的内容 2. Ctrel Alt L快速将代码格式标准化 3. Ctrl F 在当前py文件中查找 4. Ctrl R快速替换当前…

哈哈,我保研985了,之后会出一期保研经验分享

哈哈&#xff0c;我保研了&#xff0c;之后会出一期保研经验分享 个人背景 学校&#xff1a;河南某四非&#xff0c;计算机科学与技术专业英语成绩&#xff1a;四级439&#xff0c;六级438&#xff08;夏令营无六级&#xff09;科研经历&#xff1a;一个软著、国家级大创&…

如何在idea中隐藏文件或文件夹

例如我想要隐藏如下文件 只需要点击file->settings editor->file types->ignores Files and Folders-> 然后按照图片点击顺序操作即可 添加完毕点击apply->ok 隐藏成功后效果如下&#xff1a;

基于蚁狮优化的BP神经网络(分类应用) - 附代码

基于蚁狮优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于蚁狮优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.蚁狮优化BP神经网络3.1 BP神经网络参数设置3.2 蚁狮算法应用 4.测试结果&#xff1a;5.M…

EasyX图形库note4,动画及键盘交互

大家好&#xff0c;这里是Dark Flame Master&#xff0c;专栏从这篇开始就会变得很有意思&#xff0c;我们可以利用今天所学的只是实现很多功能&#xff0c;同样为之后的更加好玩的内容打下基础&#xff0c;从这届开始将会利用所学的知识制作一些小游戏&#xff0c;废话不多说&…