《数据结构》(C语言版)第1章 绪论(下)

news2024/11/15 9:25:33

第1章 绪论

  • 1.3 抽象数据类型的表示与实现
  • 1.4 算法与算法分析

1.3 抽象数据类型的表示与实现

数据类型
数据类型是一组性质相同的值的集合, 以及定义于这个集合上的一组运算的总称。

抽象数据类型(ADTs: Abstract Data Types)

  • 更高层次的数据抽象。
  • 由用户定义,用以表示应用问题的数据模型。
  • 由基本的数据类型组成,并包括一组相关的操作。

抽象数据类型可以用以下的三元组来表示

ADT = (D,S,P)
D:数据对象 S:D上的关系集 P:D上的操作集

ADT常用定义格式

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

信息隐蔽和数据封装,使用与实现相分离
在这里插入图片描述
抽象数据类型的表示与实现

  • 抽象数据类型可以通过固有的数据类型(如整型、实型、字符型等)来表示和实现。
  • 它有些类似C语言中的结构(struct)类型,但增加了相关的操作
  • 教材中用的是类C语言(介于伪码和C语言之间)作为描述工具
  • 但上机时要用具体语言实现,如C或C++等

复数—抽象数据类型的定义

ADT Complex {
 	数据对象:D={e1,e2|e1,e2∈R,R是实数集}
 	数据关系:S={<e1,e2>|e1是复数的实部,e2是复数的虚部}
 	基本操作:
 		Creat(&C,x,y)
 			操作结果:构造复数c,其实部和虚部分别被赋予参数x和y的值。
		GetReal(C)
 			初始条件:复数c已存在。
 			操作结果:返回复数c的实部值。
 		GetImag(C)
 			初始条件:复数c已存在。
 			操作结果:返回复数c的虚部值。
 		Add(C1,C2)
 			初始条件:C1,C2是复数。
 			操作结果:返回两个复数C1和C2的和。
 		Sub(C1,C2)
 			初始条件:C1,C2是复数。
 			操作结果:返回两个复数c1和C2的差。
} ADT Complex
typedef struct			//复数类型
{
	float Realpart;     //实部
	float Imagepart;    //虚部
}Complex;
void Create(&Complex C,float x,float y)
{//构造一个复数
C.Realpart=x;
C.Imagepart=y;
}
float GetReal(Complex C) 
{//取复数C=x+yi的实部
	return C.Realpart;
}
float GetImag(Complex C)
{//取复数C=x+yi的虚部
	return C.Imagepart;
}
Complex Add(Complex C1,Complex C2)
{//求两个复数C1和C2的和sum
	Complex sum;
	sum.Realpart=C1.Realpart+C2.Realpart;
	sum.Imagepart=C1.Imagepart+C2.Imagepart;
	return sum;
}
Complex Sub(Complex C1,Complex C2)
{//求两个复数C1和C2的差difference
	Complex difference;
	difference.Realpart=C1.Realpart-C2.Realpart; 
	difference.Imagepart=C1.Imagepart-C2.Imagepart; 
	return difference;
}
  1. 预定义常量及类型
//函数结果状态代码
#define OK 1 
#define ERROR 0 
#define OVERFLOW -2 

// Status是函数返回值类型,其值是函数结果状态代码。 
	typedef  int  Status; 
  1. 数据元素被约定为ElemType 类型,用户需要根据具体情况,自行定义该数据类型。
  2. 算法描述为以下的函数形式:
    函数类型 函数名(函数参数表)
    {
    语句序列;
    }
  3. 内存的动态分配与释放
    使用new和delete动态分配和释放内存空间
    分配空间 指针变量=new数据类型;
    释放空间 delete指针变量;
  4. 赋值语句
  5. 选择语句
  6. 循环语句
  7. 使用的结束语句形式有:
    函数结束语句 return
    循环结束语句 break;
    异常结束语句 exit(异常代码);
  8. 输入输出语句形式有:
    输入语句 cin (scanf)
    输出语句 cout (printf)
  9. 扩展函数有:
    求最大值 max
    求最小值 min

1.4 算法与算法分析

算法与算法分析
一个有穷的指令集,这些指令为解决某一特定任务规定了一个运算序列

算法的描述
自然语言、流程图、程序设计语言、伪码

算法的特性
输入 有0个或多个输入
输出 有一个或多个输出(处理结果)
确定性 每步定义都是确切、无歧义的
有穷性 算法应在执行有穷步后结束
有效性 每一条运算应足够基本

算法的评价
正确性、可读性、健壮性、高效性(时间代价、空间代价)

算法的效率的度量
用依据该算法编制的程序在计算机上执行所消耗的时间来度量

事后统计
利用计算机内的计时功能,不同算法的程序可以用一组或多组相同的统计数据区分

缺点
必须先运行依据算法编制的程序
所得时间统计量依赖于硬件、软件等环境因素,掩盖算法本身的优劣

事前分析估计
一个高级语言程序在计算机上运行所消耗的时间取决于:

  • 依据的算法选用何种策略
  • 问题的规模
  • 程序语言
  • 编译程序产生机器代码质量
  • 机器执行指令速度

同一个算法用不同的语言、不同的编译程序、在不同的计算机上运行,效率均不同,——使用绝对时间单位衡量算法效率不合适

时间复杂度的渐进表示法
算法中基本语句重复执行的次数是问题规模n的某个函数f(n),算法的时间量度记作:T(n)=O(f(n)) 。
表示随着n的增大,算法执行的时间的增长率和f(n)的增长率相同,称渐近时间复杂度。
数学符号“O”的定义为:若T(n)和f(n)是定义在正整数集合上的两个函数,则T(n) = O(f(n))表示存在正的常数C和n0,使得当n≥n0时都满足0≤T(n)≤Cf(n)。

算法中重复执行次数和算法的执行时间成正比的语句对算法运行时间的贡献最大
n越大算法的执行时间越长

  • 排序:n为记录数
    矩阵:n为矩阵的阶数
    多项式:n为多项式的项数
    集合:n为元素个数
    树:n为树的结点个数
    图:n为图的顶点数或边数

在这里插入图片描述
n * n阶矩阵加法

for( i = 0; i < n; i++)
	for( j = 0; j < n; j++)
		c[i][j] = a[i][j] + b[i][j];

语句的频度(Frequency Count ): 重复执行的次数:n*n;

T(n) = O (n2)

即:矩阵加法的运算量和问题的规模n的平方是同一个量级

分析算法时间复杂度的基本方法
找出语句频度最大的那条语句作为基本语句
计算基本语句的频度得到问题规模n的某个函数f(n)
取其数量级用符号“O”表示

x = 0;  y = 0;
for ( int k = 0; k < n; k ++ )
		x ++;
for ( int i = 0; i < n; i++ )
	for ( int j = 0; j < n; j++ )
		y ++;

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

时间复杂度是由嵌套最深层语句的频度决定的

void exam ( float x[ ][ ], int m, int n ) {
	float sum [ ];
	for ( int i = 0; i < m; i++ ) { 
		sum[i] = 0.0;                      
		for ( int j = 0; j < n; j++ ) 
			sum[i] += x[i][j];  
	}
	for ( i = 0; i < m; i++ )
		cout << i <<:<<sum [i] << endl; 
}

T(n) = O(mn)
f(n)=m
n

例1:N×N矩阵相乘

for(i=1;i<=n;i++)
  for(j=1;j<=n;j++)
     {c[i][j]=0;	
       for(k=1;k<=n;k++)
          c[i][j]=c[i][j]+a[i][k]*b[k][j];
     }	

T(n) = O(n3)
算法中的基本操作语句为c[i][j]=c[i][j]+a[i][k]*b[k][j];
T ( n ) = ∑ i = 1 n ∑ j = 1 n ∑ k = 1 n 1 = ∑ i = 1 n ∑ j = 1 n n = ∑ i = 1 n n 2 = n 3 = O ( n 3 ) T(n)=\sum_{i=1}^{n}\sum_{j=1}^{n}\sum_{k=1}^{n}1=\sum_{i=1}^{n}\sum_{j=1}^{n}n=\sum_{i=1}^{n}n^2=n^3=O(n^3) T(n)=i=1nj=1nk=1n1=i=1nj=1nn=i=1nn2=n3=O(n3)

例2

for( i=1; i<=n; i++) 
         for (j=1; j<=i; j++) 
             for (k=1; k<=j; k++)
    x=x+1;

定理1.1
若f(n)=amnm+am-1nm-1++a1n+a0是m次多项式,则T(n)=O(nm)。
O(nm)忽略所有低次幂项和最高次幂系数,体现出增长率的含义
语句频度 = ∑ i = 1 n ∑ j = 1 i ∑ k = 1 j = ∑ i = 1 n ∑ j = 1 i j = ∑ i = 1 n i ( i + 1 ) 2 = 1 2 ∑ i = 1 n i 2 + ∑ i = 1 n i = 1 2 ( n ( n + 1 ) ( 2 n + 1 ) 6 + n ( n + 1 ) 2 ) = n ( n + 1 ) ( n + 2 ) 6 语句频度=\sum_{i=1}^{n}\sum_{j=1}^{i}\sum_{k=1}^{j}=\sum_{i=1}^{n}\sum_{j=1}^{i}j=\sum_{i=1}^{n}\frac{i(i+1)}{2}=\frac{1}{2}\sum_{i=1}^{n}i^2+\sum_{i=1}^{n}i=\frac{1}{2}\left( \frac{n(n+1)(2n+1)}{6}+\frac{n(n+1)}{2}\right) =\frac{n(n+1)(n+2)}{6} 语句频度=i=1nj=1ik=1j=i=1nj=1ij=i=1n2i(i+1)=21i=1ni2+i=1ni=21(6n(n+1)(2n+1)+2n(n+1))=6n(n+1)(n+2)

例3:分析以下程序段的时间复杂度

i=1;   //1
while(i<=n)
	i=i*2;   //2

2f(n)≤n,即f(n)≤log2n,取最大值f(n)=log2n
所以该程序段的时间复杂度T(n) =O(log2n)

有的情况下,算法中基本操作重复执行的次数还随问题的输入数据集不同而不同
例4:顺序查找,在数组a[i]中查找值等于e的元素,返回其所在位置。

for (i=0;i< n;i++)
	if (a[i]==e) return i+1;
		return 0;

最好情况:1次;最坏情况:n;平均时间复杂度为:O(n)

当n取得很大时,指数时间算法和多项式时间算法在所需时间上非常悬殊
在这里插入图片描述
时间复杂度T(n)按数量级递增顺序为:
在这里插入图片描述
渐进空间复杂度

空间复杂度;算法所需存储空间的度量,记作: S(n)=O(f(n))
其中n为问题的规模(或大小)

算法要占据的空间;算法本身要占据的空间,输入/输出,指令,常数,变量等;算法要使用的辅助空间

例5:将一维数组a中的n个数逆序存放到原数组中。
【算法1】

for(i=0;i<n/2;i++)
	{   t=a[i];
		a[i]=a[n-i-1];
		a[n-i-1]=t;
	} 

S(n) = O(1) 原地工作

【算法2】

for(i=0;i<n;i++)
	b[i]=a[n-i-1];
for(i=0;i<n;i++)
	a[i]=b[i];

S(n) = O(n)

小结

  1. 数据、数据元素、数据项、数据结构等基本概念
  2. 对数据结构的两个层次的理解(逻辑结构、存储结构)
  3. 抽象数据类型的表示方法
  4. 算法、算法的时间复杂度及其分析的简易方法

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

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

相关文章

反贿赂体系认证:企业诚信经营的护航者

在当今商业环境中&#xff0c;企业不仅要追求经济效益&#xff0c;更要坚守诚信经营的原则。反贿赂体系认证作为现代企业合规管理的重要手段&#xff0c;不仅提升了企业的道德形象&#xff0c;还为其市场竞争力注入了强劲动力。以下是反贿赂体系认证对企业的多方面益处。 首先&…

SpringBoot集成RocketMQ消息队列

RocketMQ简介 RocketMQ是阿里巴巴2016年MQ中间件&#xff0c;使用Java语言开发&#xff0c;RocketMQ 是一款开源的分布式消息系统&#xff0c;基于高可用分布式集群技术&#xff0c;提供低延时的、高可靠的消息发布与订阅服务。同时&#xff0c;广泛应用于多个领域&#xff0c…

AUTOSAR实战教程-最通俗的讲标定协议XCP初入门

XCP是什么 XCP是什么?我们开发过程中是不是经常用串口打印出一些变量的值供自己发现问题? XCP的作用1 跟上述串口看数据类似,只不过用一组更为严格的格式规定基于CAN/ETH/FLR进行数据的观测。 XCP作用2 比串口打印数据更强大的是,XCP可以通过变量地址对变量值进行改写!…

使用 Stripe 订阅和 Firestore 集成构建大型 Streamlit 应用程序

将创意转化为软件产品的能力是一项值得学习的技能。在这篇博客中&#xff0c;我将描述需要做些什么&#xff0c;以及如何将各个部分组合在一起以创建一款无需启动成本但具有订阅模式和 Firestore 集成的软件产品。 欢迎来到雲闪世界。 无论您是数据科学家、数据工程师还是从事其…

EasyAR_稠密空间图

EasyAR稠密空间图 1.稠密空间图 EasyAR稠密空间地图利用RGB相机图像对周围环境进行三维稠密重建&#xff0c;得到稠密的点云地图和网格地图。利用稠密空间地图让虚拟物体更好的融入真实环境之中&#xff0c;用以实现真实物体和虚拟物体正确遮挡、碰撞等AR应用。 2.在Unity中的…

深度学习入门——卷积神经网络

本章的主题是卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;CNN&#xff09;。CNN被用于图像识别、语音识别等各种场合&#xff0c;在图像识别的比赛中&#xff0c;基于深度学习的方法几乎都以CNN为基础。本章将详细介绍CNN的结构&#xff0c;并用Python实…

从 Pandas 到 Polars 三十九:Polars 和 Matplotlib

Polars 与 matplotlib 配合得很好。 在matplotlib中&#xff0c;你可以直接使用polars的数据进行绘制图形&#xff0c;而无需把polars的dataframe转为pandas的dataframe&#xff1a; import polars as pl import matplotlib.pyplot as plt# 创建一个polars DataFrame df_pl …

5 道互联网大厂面试遇到的场景题

1.外卖单子只能被一个骑手接单 这是一个典型的分布式锁问题。可以采用以下几种方案: 基于Redis的分布式锁: 使用Redis的SETNX命令尝试获取锁设置合理的锁超时时间,防止死锁使用Lua脚本保证原子性操作考虑Redis集群环境下的一致性问题 基于Zookeeper的分布式锁: 创建临时顺…

openEuler系统合并home分区到root分区

为了支持国产系统底座&#xff0c;不受美帝卡脖子&#xff0c;加入openEuler&#xff0c;想把业务全部移植到openEuler系统上。在使用默认安装的情况下&#xff0c;会把home分区单独分配一个出来&#xff0c;为了方便&#xff0c;还是想合并到/根目录上。怎么做呢&#xff1f;发…

2023年码蹄杯专科组第三场初赛 解题报告 | 珂学家

前言 题解 这是2023年第三场码蹄杯职业院校算法比赛&#xff0c;3D眩晕&#xff08;字符串hash&#xff09;挺有意思的。 这个系列赛&#xff0c;喜欢出典题。 3D眩晕 难度: 钻石 思路: 字符串hash 这题难在容错性上&#xff0c;就是允许有x次修改( x ≤ 3 x \le 3 x≤3)&…

NICE Seminar(2023-07-16)|演化算法的理论研究到底有什么用?(南京大学钱超教授)

模式定理&#xff08;Schema Theorem&#xff09; 模式定理&#xff08;Schema Theorem&#xff09;是遗传算法&#xff08;Genetic Algorithm, GA&#xff09;的重要理论基础&#xff0c;由约翰霍兰德&#xff08;John Holland&#xff09;在1975年提出。它描述了具有特定模式…

【机器学习】回归类算法-相关性分析

一、前言 前面的几篇博客我们学习了分类算法&#xff0c;今天我们来了解一下回归类的算法吧。首先我们来谈谈两者有什么区别&#xff0c;首先是我们在之前的分类算法&#xff0c;这类算法可以将让我们学会如何将不同的数据划分到不同的类里面&#xff0c;输出的是一些离散的值。…

新书速览|AI创意商业广告设计:Adobe Firefly + Photoshop

《AI创意商业广告设计:Adobe Fire.yPhotoshop》 本书内容 随着AI技术的出现&#xff0c;平面设计领域也出现了利用人工智能进行创作的程序&#xff0c;比如Firefly、Midjourney、 Stable Di.usion等。这些程序能够创作出高质量的设计作品。其中&#xff0c;Fire.y是由Adobe公司…

内网权限维持——创建影子账户

文章目录 一、RID简介二、修改RID进行权限维持 影子账户&#xff0c;顾名思义就是隐藏的用户&#xff0c;无法通过“计算机管理”或命令行查询&#xff0c;只能在注册表中找到其信息。下面的实验是在win 7上进行的。真正的影子账户其实是windwos RID 劫持。 一、RID简介 在wi…

线程池工具类 Executors源代码详解

​ 快捷导航 一、提供了什么功能&#xff1f;源码中的定义&#xff1a;此类支持以下几种方法&#xff1a; 二、源码中是怎么实现的&#xff1f;1、创建并返回一个配置了常用设置的ExecutorServicenewFixedThreadPool()newSingleThreadExecutor()newCachedThreadPool()newWorkS…

学习C#调用LazyCaptcha模块生成验证码的基本用法

LazyCaptcha是仿EasyCaptcha和SimpleCaptcha的.net开源图形验证码模块&#xff0c;其支持生成验证码及对应的静态图或动态图&#xff0c;还支持在图形中增加气泡、干扰线等噪音以提升图片自动识别难度。LazyCaptcha既能在B/S程序中使用&#xff08;本文的原由即Admin.NET中使用…

【数据结构初阶】深度理解 “栈” (附源码)

hello&#xff0c;又见面了&#xff01; 目录 1. 栈的概念与结构 2、栈的实现 Stack.h Stack.c test.c 3、习题 正文开始—— 1. 栈的概念与结构 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端…

小试牛刀-Telebot区块链游戏机器人(TS升级)

目录 1.编写目的 2.为什么使用TypeScript实现? 3.实现功能 3.1 AI图片生成 3.2 签到 3.3 邀请 3.4 WalletConnect连接 4.功能实现详解 4.1 AI图片生成 4.2 签到 4.3 邀请 4.4 WalletConnect连接 5.功能截图 ​6.问题整理 Welcome to Code Blocks blog 本篇文章主…

塑造美好心灵,激发创造活力|第三届瓷艺中华“陶溪川杯”儿童青少年陶瓷作品展开展

第三届瓷艺中华“陶溪川杯”儿童青少年陶瓷作品展 展览现场 由中央美术学院、景德镇陶瓷大学、景德镇陶文旅控股集团共同主办&#xff0c;由中国非物质文化遗产保护协会陶瓷分会、中国文化艺术发展促进会陶瓷专业委员会、中央美术学院陶瓷艺术研究院、中央美术学院少儿美术教…

无人机无刷电机技术详解及选型

1. 技术原理 无人机无刷电机&#xff08;Brushless DC Motor, BLDC&#xff09;是现代无人机动力系统的核心部件&#xff0c;其工作原理基于电磁感应和换向技术&#xff0c;实现了无需物理接触即可持续旋转的高效率动力输出。与传统有刷电机相比&#xff0c;无刷电机通过电子换…