分析和设计算法

目录

前言 

循环不变式

n位二进制整数相加问题

RAM模型

使用RAM模型分析

代码的最坏情况和平均情况分析

插入排序最坏情况分析

插入排序平均情况分析

设计算法

分治法

总结


前言 

        循环迭代,分析算法和设计算法作为算法中的三个重要的角色,下面从一些程序示例入手,介绍如何使用有效的方法来设计和分析算法。

循环不变式

代码:

int f(int n) {int res = 1;for(int i = 1; i <= n; i++) {res = res * i;}return res;
}

这是求n!的函数, res是每次迭代的(i-1)!的结果,可以看到每趟迭代下来,它的形式都是res,没有变更过,我们称之为循环不变式

循环不变式有初始化,保持和终止三要素。

初始化:循环的第一次迭代,它为真。代码中如果res = 0; 则第一次迭代的结果res = 0;

结果为假,初始化错误。

保持:如果本次迭代结果为真,则下一次的结果也为真。本次res = i!, 下一次res = res * (i+1) = i! * (i + 1) = (i+1)!. 可以理解为迭代保持了。

终止:迭代终止的条件, i > n时,迭代终止。数学归纳法中只有初始化和保持的证明,但是没有终止这一步。当i叠加到n+1时,上一次迭代结果时res = res*i = i! = n!已经是正确结果了,所以迭代条件终止时,结果正确。

n位二进制整数相加问题

初始化:A[MAXSIZE] = {0}, B[MAXSIZE] = {0}, C[MAXSIZE] = {0}.

保持:C[i+1] = (A[i] + B[i] + C[i])/2; C[i] = (A[i] + B[i] + C[i])%2.

终止条件:A[i]和B[i]中全部为零,迭代终止.

代码:

void num_to_binary(int num, int B[MAXSIZE]) {for (int i = 0; num > 0; i++){B[i] = num % 2;num = num / 2;printf("%d", B[i]);}printf("\n");}void binary_add(int A[MAXSIZE], int B[MAXSIZE], int C[MAXSIZE + 1]) {int i;for (i = 0; B[i] || A[i] ; i++){C[i+1] = (A[i] + B[i] + C[i]) / 2;C[i] = (A[i] + B[i] + C[i]) % 2;printf("%d", C[i]);}printf("%d\n", C[i]);
}

输出结果:

RAM模型

在分析算法时,我们经常提到时间复杂度和空间复杂度。这些都是基于代码中的指令是一条一条地在CPU中执行的,不存在并行操作。这种前提可以理解位RAM模型。

使用RAM模型分析

代码

代价

次数

int res = 1;

C1

1

for(int i = 1; i <= n; i++)

C2

n

res = res * i;

C3

n

return res;

C4

1

上述代码的运行时间位Tn=c1+c2*n+c3*n+c4.

T(n)为n的线性函数,所以可以说改代码的时间复杂度为O(n).

代码的最坏情况和平均情况分析

  for(int i = 0; i < 10; i++) {while (p->next){lnode *q = p->next;if(q->data > data[i]) {lnode *node = (lnode *) malloc(sizeof(lnode));node->data = data[i];node->next = q;p->next = node;break;}p = p->next;}p = list;
}
}
插入排序最坏情况分析

10个元素参与插入排序,最坏情况下,每趟插入的位置都是表尾:

第一趟  比较1次

第二趟  比较2次

。。。

第n趟  比较n次

T(n) = (1+2+3+…+n) + c = (n+1)*n/2 + cn.(c为插入一个结点的时间复杂度)。

插入排序平均情况分析

平均比较次数:

第一趟 比较(1+1)/2

第二趟 比较(1+2)/2

。。。

第n趟 比较(1+n)/2

T(n) = n*n/4 + cn.

在n足够大的时候,可以认为插入排序的最坏情况和平均情况的时间复杂度均为O(n*n).

设计算法

分治法

分治三个步骤:

分解:分解原问题为子问题,这些子问题为原问题的较小规模的问题。

解决:递归地解决这些子问题,如果规模小到一定程度,则直接得出答案。

合并:合并上述解决地子问题地解,得出最终解。

前提:该集合S经过归并排序之后的序列再进行如下算法运算。

分解:集合S的n个问题分解成两个规模n/2的问题。

解决:递归的解决和分解这些子问题,直到规模为2时,两个数相加与x比较,如果相等则存在,否则返回不存在。

合并:合并两个子问题,两个子问题中不存在和等于x的情况,所以需要判断是否存在跨集合相加和等于x的情况。

代码:

#include "stdio.h"
#define OK 1
#define ERROR 0
#define MAXSIZE 10
int FLAG = 0;
int is_x(int a1[MAXSIZE], int x, int low, int mid, int high);
void jude_add_x(int a[MAXSIZE], int x, int low, int high);void main() {int b[10] = {-1,2,3,5,9,27,29,38,49,74};int x = 8;jude_add_x(b, x, 0, 9);printf("The result is %d", FLAG);
}int is_x(int a1[MAXSIZE], int x, int low, int mid, int high) {int i = low, j = mid+1, k = low;while (i <= mid || j <= high){if(a1[i] + a1[j] == x) {return OK;}else if(a1[i] + a1[j] < x) {if(i < mid) i++;else if( j <= high) j++;else return ERROR;}else {return ERROR;}} return ERROR;
}void jude_add_x(int a[MAXSIZE], int x, int low, int high) {if(low == high) {return;}int mid = (low + high) / 2;jude_add_x(a, x, low, mid);jude_add_x(a, x, mid + 1, high);if(low != high && is_x(a, x, low, mid, high)) FLAG = 1;
}

 输出结果:

时间复杂度:O(lgn*n) 

空间复杂度:   O(1)

总结

本文主要讲解如何分析和设计算法。分析算法从分析时间复杂度入手,讲述了最坏情况和平均情况下的分析。设计算法以一个程序入手,讲述了分治法的三个步骤怎么分析。

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

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

相关文章

Java——二进制原码、反码和补码

一、简要介绍 原码、反码和补码只是三种二进制不同的表示形式&#xff0c;每个二进制数都有这三个形式。 1、原码 原码是将一个数的符号位和数值位分别表示的方法。 最高位为符号位&#xff0c;0表示正&#xff0c;1表示负&#xff0c;其余位表示数值的绝对值。 例如&…

如何解决游戏行业DDOS攻击问题

随着网络游戏行业的迅速发展&#xff0c;网络游戏问题也不可忽视&#xff0c;特别是目前网络攻击频发&#xff0c;DDoS攻击的简单化以及普及化&#xff0c;对游戏来说存在非常大的安全威胁。 随着受攻击对象的范围在不断地拓展&#xff0c;网络游戏这种这种新型并且有着丰厚利…

Scala编程基础3 数组、映射、元组、集合

Scala编程基础3 数组、映射、元组、集合 小白的Scala学习笔记 2024/5/23 14:20 文章目录 Scala编程基础3 数组、映射、元组、集合apply方法数组yield 数组的一些方法映射元组数据类型转换求和示例拉链集合flatMap方法 SetHashMap apply方法 可以new&#xff0c;也可以不new&am…

flink Jobmanager metaspace oom 分析

文章目录 现象作业背景分析现象分析类卸载条件MAT 分析 解决办法flink 官方提示 现象 通过flink 页面提交程序&#xff0c;多次提交后&#xff0c;jobmanager 报metaspace oom 作业背景 用户代码是flink 代码Spring nacos 分析 现象分析 从现象来看肯定是因为有的类没有被…

Linux系统-前台任务组,后台任务组

文章目录 前台进程后台进程新命令jobsfg 【后台进程组序号】ctrlz组合键信号 和 bg命令ctrlz组合键信号bg 【后台进程组序号】 session会话此时我们关闭本次的会话&#xff0c;我们的后台进程是否也会退出呢&#xff1f; 总结 前台进程 在我们远程登录Linux服务器后&#xff0…

创建__init__()方法

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在创建类后&#xff0c;可以手动创建一个__init__()方法。该方法是一个特殊的方法&#xff0c;类似Java语言中的构造方法。每当创建一个类的新实例时…

【AI界的狼人杀】人工智能“反图灵测试”实验

5月28日&#xff0c; AI Power Users、Unity 独立开发者&#xff1a;Tore Knabe 在其社交平台发布了一则名为《Reverse Turing Test Experiment with AIs》的视频&#xff0c;立马引发了热议。 视频中共出现了五位主要角色&#xff0c;“他们”分别是&#xff1a;亚里士多德&am…

961操作系统知识总结

部分图片可能无法显示&#xff0c;参考这里&#xff1a;https://zhuanlan.zhihu.com/p/701247894 961操作系统知识总结 一 操作系统概述 1. 操作系统的基本概念 重要操作系统类型&#xff1a;批处理操作系统(批量处理作业&#xff0c;单道批处理/多道批处理系统&#xff0c;用…

RabbitMQ-直连交换机(direct)使用方法

RabbitMQ-默认读、写方式介绍 RabbitMQ-发布/订阅模式 目录 1、概述 2、直连交换机 3、多重绑定 4、具体代码实现 4.1 生产者部分 4.2 消费者部分 5、运行代码 6、总结 1、概述 直连交换机&#xff0c;可以实现类似路由的功能&#xff0c;消息从交换机发送到哪个队列…

夜天之书 #98 Rust 程序库生态合作的例子

近期主要时间都在适应产品市场&#xff08;Product Marketing&#xff09;的新角色&#xff0c;不少想法还在酝酿和斟酌当中&#xff0c;于是文章输出没有太多时间来推敲和选题&#xff0c;只能保持每月发布相关的进展或一些零碎的思考。或许我可以恢复最早的模式&#xff0c;多…

YOLOv8改进(一)-- 轻量化模型ShuffleNetV2

文章目录 1、前言2、ShuffleNetV2代码实现2.1、创建ShuffleNet类2.2、修改tasks.py2.3、创建shufflenetv2.yaml文件2.4、跑通示例 3、碰到的问题4、目标检测系列文章 1、前言 移动端设备也需要既准确又快的小模型。为了满足这些需求&#xff0c;一些轻量级的CNN网络如MobileNe…

十_信号4-SIGCHLD信号

SIGCHLD信号 在学习进程控制的时候&#xff0c;使用wait和waitpid系统调用何以回收僵尸进程&#xff0c;父进程可以阻塞等待&#xff0c;也可以非阻塞等待&#xff0c;采用轮询的方式不停查询子进程是否退出。 采用阻塞式等待&#xff0c;父进程就被阻塞了&#xff0c;什么都干…

力扣83. 删除排序链表中的重复元素

Problem: 83. 删除排序链表中的重复元素 文章目录 题目描述思路复杂度Code 题目描述 思路 1.定义快慢指针fast、slow均指向head&#xff1b; 2.每次fast后移一位&#xff0c;当fast和slow指向的节点值不一样时&#xff0c;将slow.next指向fast同时使slow指向fast&#xff1b; 3…

MyBatis框架-开发方式+参数传递+#{}、${}+返回值处理+查询结果封装为对象+resultType

一、开发方式 MyBatis-Dao层Mapper接口化开发 二、注意事项 1、Mapper接口与Mapper.xml映射文件要满足4个对应 &#xff08;1&#xff09;Mapper接口的全类名必须与Mapper映射文件中的namespace相同 &#xff08;2&#xff09;Mapper接口中的每一个方法名在Mapper映射文件…

回溯算法之电话号码字母组合

题目&#xff1a; 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 示例 1&#xff1a; 输入&#xff1a;digits "2…

Java web应用性能分析之【jvisualvm远程连接云服务器】

Java web应用性能分析之【java进程问题分析概叙】-CSDN博客 Java web应用性能分析之【java进程问题分析工具】-CSDN博客 前面整理了java进程问题分析和分析工具&#xff0c;现在可以详细看看jvisualvm的使用&#xff0c;一般java进程都是部署云服务器&#xff0c;或者托管IDC机…

每周统计-20240531

用于测试程序的稳定性&#xff1a; 龙虎榜&#xff1a; 成交额&#xff1a; 封成比&#xff1a; 收盘前放量&#xff1a; 开盘抢筹&#xff1a; 封单额&#xff1a;

论文阅读:Correcting Motion Distortion for LIDAR HD-Map Localization

目录 概要 Motivation 整体架构流程 技术细节 小结 论文地址&#xff1a;http://arxiv.org/pdf/2308.13694.pdf 代码地址&#xff1a;https://github.com/mcdermatt/VICET 概要 激光雷达的畸变矫正是一个非常重要的工作。由于扫描式激光雷达传感器需要有限的时间来创建…

linux命令:调试必备工具dmesg

在服务器上进行芯片调试时&#xff0c;我们会遇到各种各样的问题&#xff0c;很多问题与操作系统相关。此时就需要了解操作系统发生了哪些事件。 dmesg 是linux系统中用来打印或控制内核缓冲区内容的命令。这个环形缓冲区记录了系统启动以来发生的各种事件消息&#xff0c;包括…

ChatTTS改良版 - 高度逼真的人类情感文本生成语音工具(TTS)本地一键整合包下

先介绍下ChatTTS 和之前发布的 Fish Speech 类似&#xff0c;都是免费开源的文本生成语音的AI软件&#xff0c;但不同的是&#xff0c;ChatTTS测试下来&#xff0c;对于人类情感语调的模仿&#xff0c;应该是目前开源项目做的最好的&#xff0c;是一款高度接近人类情感、音色、…