【算法】算法初步

news2025/1/8 7:04:13

要学好数据结构和算法的设计与分析,请务必先打好C语言基础,因为C语言中的数据存储、内存映射、指针等等概念最接近计算机的底层原理,数据结构是数据在内存空间当中的组织形式,而算法则是提供了解决某个问题的一种思路,而数据结构与算法设计一定会涉及到最核心的部分:提升性能 —— 时间和空间的问题。如果有一个好的算法,它的执行时间很短,占用空间很小,数据结构的组织形式最优,这才是我们想要看见的结果。

算法为解决某个问题提供了一种思路,我们尝试让这种思路达到最优。

瑞士科学家沃思(N.Wirth)的著名公式:数据结构 + 算法 = 程序

C语言对内存的操作更加直观、方便、简洁,数据结构不过是数据在内存映射当中的组织形式,所以,透过C语言我们可以更加直接清晰的表达数据结构与算法的底层,C语言更接近计算机语言的底层。例如,在Java中,通过类对于数组、链表、栈等操作已经封装好了,虽然也可以使用但没有C语言直观的能看见数据在内存映射中的实际状态,所以我们尽可能都使用C语言来作为这门课的描述性语言。而且,根据不同的数据结构,我们将会采用不同的算法,在不同的应用场景中,算法的设计也不同。所以,我们使用C语言作为基础,因为对于一件事物的理解越接近底层离真相越近。

在我的资源中分别上传了两份资源:数据结构和算法(自整理),需要的朋友自取,(已经整理好了,直接使用文件中的内容掌握数据结构与算法这门课足够了)。

数据结构的概念

数据结构 (Data Structure):数据结构指的是 数据元素及数据元素之间的相互关系,或组织数据的形式。 有人认为:按照某种逻辑关系组织起来的一批数据,应用计算机语言,按照一定的存取方式把它们存储到计算机存储器中,并为这些数据定义一个运算集合,就称为一个数据结构。

数据结构包含下面三方面的内容:

  1. 数据的逻辑结构:表示数据运算之间的抽象关系(如邻接关系、从属关系等),按每个元素可能具有的直接前趋数和直接后继数将逻辑结构分为“线性结构”和“非线性结构”两大类。
  2. 数据的存储结构:逻辑结构在计算机中的具体实现方法,分为顺序存储方法、链接存储方法、索引存储方法、散列存储方法。
  3. 对数据结构施加的运算:对数据进行的操作,如插入、删除、查找、排序等 。
    请添加图片描述
  • 数据类型可分为:非结构的原子类型和结构类型。
    • 原子类型的值是不可分解的
    • 结构类型的值是由若干成分按某种结构组成的。

数据类型在高级语言中指数据的取值范围及其上可进行的操作的总称

C语言中,提供 int, char,float,double 等基本数据类型,数组、结构体、共用体、枚举等构造数据类型,还有指针、空(void)类型等。用户也可用 typedef 自己定义数据类型

typedef   struct  
{      
	int   num;
	char  name[20];
	float score;
}STUDENT;
STUDENT    stu1,stu2, *p;
抽象数据类型:

是指一个数学模型以及定义在该模型上的一组操作。抽象数据类型和数据类型实质上是一个概念,它仅取决于数据类型的逻辑性,而与其在计算机内部如何表示和实现是无关的。

也就是说抽象数据类型的定义由一个值域和定义在该值域上的一组操作组成。

抽象数据类型的定义:

抽象数据类型名
{
	数据对象:〈数据对象的定义〉
	数据关系:〈数据关系的定义〉
	基本操作:〈基本操作的定义〉
} 抽象数据类型名

数据对象和数据关系的定义用伪码描述:
数据基本操作的定义格式:

基本操作名(参数表)
初始条件:〈初始条件描述〉
操作结果:〈操作结果描述〉

抽象数据类型可通过固有数据类型来表示和实现,即利用处理器中已存在的数据类型来说明新的结构,用已经实现的操作来组合新的操作。

算法

算法(Algorithm)是一个有穷规则(或语句、指令)的有序集合。 它确定了解决某一问题的一个运算序列。对于问题的初始输入,通过算法有限步的运行,产生一个或多个输出。

举一个例子,常规简单数学题:求两正整数m、n的最大公因子。 算法如下:

	① 输入m,n; 	 
	② m/n(整除),余数→r (0≤r≤n);
	③ 若r=0,则当前n=结果,输出n,算法停止;否则,转④;
	④ n→m,r->n; 转②。

如初始输入 m=10,n=4,则m,n,r 在算法中的变化如下:

	m          n            r
	10         4            2
	4          2            0(停止)  

即10和4 的最大公因子为2。

算法特性

(1)    有穷性 —— 算法执行的步骤(或规则)是有限的;
(2)    确定性 —— 每个计算步骤无二义性;
(3)    可行性 —— 每个计算步骤能够在有限的时间内完成;
(4)    输入 —— 算法有一个或多个外部输入;
(5)    输出 —— 算法有一个或多个输出。

这里要说明的是,算法与程序既有联系又有区别。二者都是为完成某个任务,或解决某个问题而编制的规则(或语句)的有序集合,这是它们的共同点。区别在于:其一,算法与计算机无关,但程序依赖于具体的计算机语言。其二,算法必须是有穷尽的,但程序可能是无穷尽的。其三,算法可忽略一些语法细节问题,重点放在解决问题的思路上,但程序必须严格遵循相应语言工具的语法。算法转换成程序后才能在计算机上运行。另外,在设计算法时,一定要考虑它的确定性,即算法的每个步骤都是无二义性的(即一条规则不能有两种以上的解释)

解决一个问题可以有多种不同的算法,在算法正确的前提下,评价算法好坏的方法 :

消耗时间的多少 :
消耗存储空间的多少 :
容易理解、容易编程和调试、容易维护。
时间复杂度的概念介绍 :
问题的规模:输入数据量的大小,用n来表示。
算法的时间复杂度 :算法消耗时间,它是问题规模的函数 T(n)。

将上述 求两正整数m、n的最大公因子。 算法思路转换成C语言程序如下:

#include “stdio.h”
int main(void)
{ 
	int m,n, j;  char flag=‘Y’;
	while (flag==‘y’||flag==’Y’)
	{ 
		printf(“\n”);
		scanf(“input= %d%d”,&m,&n);  //输入两个整数m,n//
		if (m>0 && n>0 )
		{ 
			j=maxog(m,n) ;            //求m,n的最大公因子//
			printf (“output= %d\n”,j); } //输出结果//
			printf (continue?(y/n));
			flag=getchar();              //输入’y’或’Y’继续,否则停止//
       }
    }

int maxog(int m, int n)    //求m、n的最大公因子算法(或函数)//
{	 
	int r=m%n;
	while ( r!=0)
	{ 
		m=n;  
		n=r;  
		r=m%n; 
	}
	return (n);  
}

前提:算法均以C语言的函数形式描述,而main() 和 数据 I/O 就不描述了。另外,由于某种原因(如参数错,存储分配失败等)导致算法无法继续执行下去时,约定调用函数 ERROR() 进行出错处理。

数据结构是研究从具体问题中抽象出来的数学模型如何在计算机存储器中表示出来;而算法研究的是对数据处理的步骤。如果对问题的数据表示和数据处理都做出了具体的设计,就相当于完成了相应的程序。编写代码执行层只是最后一步实现步骤。

算法分析初步

算法分析是指算法在正确的情况下,对其优劣的分析。一个好的算法通常是指:

  1. 算法对应的程序所耗时间少;
  2. 算法对应的程序所耗存储空间少;
  3. 算法结构性好、易读、易移植和调试等等。

算法的时间效率

算法对应程序的时耗,有诸多因素,主要考虑程序中可执行语句的执行次数。为此,引入下面几个概念:

  1. 语句的频度(Frequency Count)

语句频度定义为可执行语句在算法(或程序)中重复执行的次数。若某语句执行一次的时间为t,执行次数为f,则该语句所耗时间的估计为 t*f。

请添加图片描述
请添加图片描述

  1. 算法的时间复杂度(Time Complexity)

算法的时间复杂度定义为算法中可执行语句的频度之和,记为T(n)。T(n)是算法所需时间的一种估计,其中n为问题的规模(或大小、体积)。如上图中,问题的规模n为矩阵的阶,该算法的时间复杂度为:

T(n)=(n+1)+n(n+1)+n2+n2(n+1)+n3=2n3+3n2+2n+1

当n->∞时,lim(T(n)/n3)=2,故T(n)与n3为同阶无穷大,或说T(n)与n3成正比、T(n)的量级为n3,记为:T(n) = O (n3)

例2:在数组中查找

在数组(A[1],A[2], …, A[n])中查找最后一个与给定值k相等的元素的序号的算法

 int search(datatype A[n+1], datatype k) 
{    int i=n; A[0]=k;
       while (i>0 && A[i]!=k)  i--;
      return(i);
}

本例应以平均查找次数为算法的T(n)。设查找每个元素的概率pi(1≤i≤n)均等,即pi=1/n,查找元素k时,k与A[i] 的比较次数(即执行while循环语句的次数)Ci=n-(i+1),,则查找次数的平均值(或期望值):
因此,请添加图片描述
故T(n)=O(n),此时又称T(n)为算法的渐进时间复杂度。

算法效率的度量

  • 算法效率——用依据该算法编制的程序在计算机上执行所消耗的时间来度量。(算法时间是由控制结构和原操作的决定的)
  • 记号——引用了 “O”“O” 表示一个 数量级的概念。
    根据算法中语句执行的最大次数(频度)来 估算一个算法执行时间的数量级
  • 时间复杂度:算法中基本操作重复执行的次数是问题规模n的某个函数f(n),

T(n)=O(f(n))

它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同。

  • 语句的频度:是该语句重复执行的次数。

T(n)的量级通常有:

O© —— 常数级,不论问题规模多大,T(n) 一致,因而是理想的T(n)量级;
O(n) —— 线性级;O(n2),O(n3) —— 平方、立方级;
O(log2n),O(n*log2n) —— 对数、线性对数级;
O(2n) —— 指数级,时间复杂度最差。

以上几种常见的T(n)随n变化 的增长率可以如图所示:

请添加图片描述
对较为复杂的算法,可分段分析其时间复杂度。如某算法可分为两部分,其时间复杂度分别为:

T1(n)=O(f(n)) , T2(n)=O(g(n))

此时两部分问题的体积一致,则总的 T(n)=T1(n)+T2(n)=O(max(f(n),g(n))
O(max(f(n),g(n)) 表示取 f(n)、g(n) 中最大者。

但若 T1(m)=O(f(m)) , T2(n)=O(g(n)),两部分的体积不一致,则:

T(m,n)= T1(m)+ T2(n)=O(f(m)+g(n))

另外,算法空间复杂度的定义:
设算法对应问题的体积(或规模)为n,执行算法所占存储空间的量级为D(n),则D(n)为算法的空间复杂度(Space Complexity)。

#define n 100 
void MatrixMultiply(int A[n][n],int B[n][n],int C[n][n])
{	int i,j,k
	 for (i=1;i<=n;++i)                      //n+1
		for (j=1;j<=n;++j)                   // n*(n+1)
		   { C[i][j]=0;                      //n2
			for (k=1;k<=n,k++)    n2(n+1)
				C[i][j]=C[i][j]+a[i][k]*b[k][j];   //n3
         }
}
T(n)=n+1+n*(n+1)+n2+n2(n+1)+n3=2n3+3n2+2n+1

量级:T(n)=O(n3)
请添加图片描述

以上。仅供学习与分享交流,请勿用于商业用途!转载需提前说明。

我是一个十分热爱技术的程序员,希望这篇文章能够对您有帮助,也希望认识更多热爱程序开发的小伙伴。
感谢!

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

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

相关文章

年会抽奖Html

在这里插入图片描述 <!-- <video id"backgroundMusic" src"file:///D:/background.mp3" loop autoplay></video> --> <divstyle"width: 290px; height: 580px; margin-left: 20px; margin-top: 20px; background: url(D:/nianhu…

LLM 实现Malleable 软件

All computer users may soon have the ability to author small bits of code. What structural changes does this imply for the production and distribution of software? 如果每个终端用户都能修改一部分代码&#xff0c; 这个将会对软件的生产和分发有何重大改变&#…

国产编辑器EverEdit - 两种删除空白行的方法

1 使用技巧&#xff1a;删除空白行 1.1 应用场景 用户在编辑文档时&#xff0c;可能会遇到很多空白行需要删除的情况&#xff0c;比如从网页上拷贝文字&#xff0c;可能就会存在大量的空白行要删除。 1.2 使用方法 1.2.1 方法1&#xff1a; 使用编辑主菜单 选择主菜单编辑 …

出租号平台网站系统源码/单合租用模式 提供用户提现功能

这是一款租号平台源码&#xff0c;采用常见的租号模式对接的易支付。目前网络上还很少见到此类类型的源码。 程序采用thinkphp6.0开发&#xff0c;前端采用layui 程序开发&#xff1a;PHPMySQL 程序演示&#xff1a;zh1.yetukeji.top, 账户 13112215717 &#xff0c;密码qq2…

C++:位与运算符

& 一&#xff0c;位与运算符的运算规则 有0则0。 二&#xff0c;判断奇偶性 %&#xff1a;优先级高&#xff0c;效率低 &&#xff1a;优先级低&#xff0c;效率高 数与1的位与运算结果为1则为奇数&#xff0c;结果为0则为偶数 三&#xff0c;获取一个数二进制的后…

第 31 章 - 源码篇 - Elasticsearch 写入流程深入分析

写入源码分析 接收与处理 请求首先会被 Netty4HttpServerTransport 接收&#xff0c;接着交由 RestController 进行路由分发。 private void tryAllHandlers(final RestRequest request, final RestChannel channel, final ThreadContext threadContext) throws Exception {…

C语言----指针

目录 1.概念 2.格式 3.指针操作符 4.初始化 1. 将普通变量的地址赋值给指针变量 a. 将数组的首地址赋值给指针变量 b. 将指针变量里面保存的地址赋值给另一个指针变量 5.指针运算 5.1算术运算 5.2 关系运算 指针的大小 总结&#xff1a; 段错误 指针修饰 1. con…

Java高频面试之SE-09

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本牛马baby今天又来了&#xff01;哈哈哈哈哈嗝&#x1f436; final关键字有什么作用&#xff1f; 在 Java 中&#xff0c;final 关键字有多个用途&#xff0c;它可以用于类、方法和变量。根据使用的上…

ChatGPT 主流模型GPT-4/GPT-4o mini的参数规模是多大?

微软论文又把 OpenAI 的机密泄露了&#xff1f;&#xff1f;在论文中明晃晃写着&#xff1a; o1-preview 约 300B&#xff1b;o1-mini 约 100BGPT-4o 约 200B&#xff1b;GPT-4o-mini 约 8BClaude 3.5 Sonnet 2024-10-22 版本约 175B微软自己的 Phi-3-7B&#xff0c;这个不用约…

某纪检工作委员会视频监控网络综合运维项目

随着某纪检工作委员会信息化建设的不断深入&#xff0c;网络基础设施的数量持续增加&#xff0c;对网络设备的运维管理提出了更为复杂和艰巨的要求。为了确保这些关键信息基础设施能够安全稳定地运行&#xff0c;该纪检工作委员会决定引入智能化运维管理系统&#xff0c;以科技…

显示器太薄怎么用屏幕挂灯?使用前先了解屏幕挂灯的最佳角度

人们对用眼健康的重视以及数字化办公和娱乐的普及&#xff0c;屏幕挂灯作为一种能够有效减少屏幕反光、保护眼睛的照明设备&#xff0c;受到了越来越多消费者的青睐。随着科技的进步&#xff0c;显示器设计日益轻薄&#xff0c;为我们的桌面节省了空间并带来了美观的视觉效果。…

HTTP/HTTPS ②-Cookie || Session || HTTP报头

这里是Themberfue 上篇文章介绍了HTTP报头的首行信息 本篇我们将更进一步讲解HTTP报头键值对的含义~~~ ❤️❤️❤️❤️ 报头Header ✨再上一篇的学习中&#xff0c;我们了解了HTTP的报头主要是通过键值对的结构存储和表达信息的&#xff1b;我们已经了解了首行的HTTP方法和UR…

excel快速计算周数的方法

业务中经常要通过周汇总计算&#xff0c;为方便后续汇总在源数据引入“周”列 公式&#xff1a; "W"&IF((ROW()1)/7<1,1,ROUNDUP((ROW()1)/7,0))函数释义&#xff1a; ①一周有7天&#xff0c;如果1月1号刚好是从周一开始&#xff0c;那么计算周数可以简单得…

redis各种数据类型介绍

Redis 是一种高性能的键值存储数据库&#xff0c;它支持多种数据类型&#xff0c;使得开发者可以灵活地存储和操作数据。以下是 Redis 支持的主要数据类型及其介绍&#xff1a; 1. 字符串&#xff08;String&#xff09; 字符串是 Redis 中最基本的数据类型&#xff0c;它可以存…

Python 模块,包(详解)

一. 引用变量 引用变量&#xff1a;值的传递通常可以分为两种方式&#xff0c;一种是值的传递&#xff0c;一种是引用地址传递&#xff0c;在Python中一般都是用引用地址传递 变量名和对象&#xff1a;变量名&#xff08;如 a&#xff09;和它指向的对象&#xff08;如整数 5&a…

RabbitMQ发布确认高级篇(RabbitMQ Release Confirmation Advanced Edition)

系统学习消息队列——RabbitMQ的发布确认高级篇 简介 ‌RabbitMQ是一个开源的消息代理软件&#xff0c;实现了‌高级消息队列协议&#xff08;AMQP&#xff09;‌&#xff0c;主要用于在分布式系统中进行消息传递。RabbitMQ由‌‌Erlang语言编写&#xff0c;具有高性能、健壮…

封装/前线修饰符/Idea项目结构/package/impore

目录 1. 封装的情景引入 2. 封装的体现 3. 权限修饰符 4. Idea 项目结构 5. package 关键字 6. import 关键字 7. 练习 程序设计&#xff1a;高内聚&#xff0c;低耦合&#xff1b; 高内聚&#xff1a;将类的内部操作“隐藏”起来&#xff0c;不需要外界干涉&#xff1b…

【代码随想录】刷题记录(89)-分发糖果

题目描述&#xff1a; n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 每个孩子至少分配到 1 个糖果。相邻两个孩子评分更高的孩子会获得更多的糖果。 请你给每个孩子分发糖果&#xff0…

Ae:合成设置 - 3D 渲染器

Ae菜单&#xff1a;合成/合成设置 Composition/Composition Settings 快捷键&#xff1a;Ctrl K After Effects “合成设置”对话框中的3D 渲染器 3D Renderer选项卡用于选择和配置合成的 3D 渲染器类型&#xff0c;所选渲染器决定了合成中的 3D 图层可以使用的功能&#xff0…

掌握RabbitMQ:全面知识点汇总与实践指南

前言 RabbitMQ 是基于 AMQP 高级消息队列协议的消息队列技术。 特点&#xff1a;它通过发布/订阅模型&#xff0c;实现了服务间的高度解耦。因为消费者不需要确保提供者的存在。 作用&#xff1a;服务间异步通信&#xff1b;顺序消费&#xff1b;定时任务&#xff1b;请求削…