1.数据结构与算法—前言

程序=数据结构+算法

1 数据结构的研究内容

在这里插入图片描述
计算机求解问题的步骤:①具体问题抽象为数学模型(实质为分析问题,提取操作对象,找出操作对象之间的关系,用数学语言描述);②设计算法;③编程、调试、运行。
随着计算机应用领域的发展,计算机越来越多地用于非数值计算。
例1:学生学籍管理系统
在这里插入图片描述
操作对象:每位学生的信息(学号、姓名、性别、籍贯、专业)
操作算法:查询、插入、修改、删除等;
操作对象之间的关系:线性关系;
数据结构:线性数据结构、线性表。
类似的还有图书管理系统、人事管理系统、仓库管理系统、通讯录等等。
例2:人机对弈问题
在这里插入图片描述
操作对象:棋局的状态;
操作算法:走棋,即选择一种策略使棋局状态发生变化;
操作对象之间的关系:非线性关系;
数据结构:树。
例3:地图导航—求最短路径
在这里插入图片描述
操作对象:点和线(位置与路径);
操作算法:求最短路径;
操作对象之间的关系:网状结构(非线性关系);
数据结构:图。
小结:数据结构是一门研究非数值计算的程序设计中计算机的操作对象以及它们之间的关系和操作的学科。

2 基本概念及术语

2.1 数据、数据元素、数据项和数据对象

2.1.1 数据(Data)

在将具体问题抽象为数学模型的时候,我们需要将要处理的信息抽象到计算机内部以保证计算机能够识别到信息。因此,数据的定义为:能输入计算机且能被计算机处理的各种符号的集合。特点:①信息的载体;②是对客观事物符号化的表示;③能够被计算机识别、存储和加工。数据包括数值型数据(整数、实数等)和非数值型数据(文字、图像、图形、声音等)。

2.1.2 数据元素(Data Element)

是数据的基本单位,通常作为一个整体进行考虑。简称为元素(记录或节点),一个数据元素通常由多个数据项组成。
在这里插入图片描述
例如:学生表中的第二个学生就是一个数据元素,这个数据元素由(学号、姓名、性别、籍贯等数据项组成)。

2.1.3 数据项(Data Element)

构成数据元素的不可分割的最小单位。
数据、数据元素和数据项三者的关系:
数据>数据元素>数据项(数据由数据元素组成,数据元素由数据项组成,学生表>个人信息>学号、姓名…)

2.1.4 数据对象(Data Object)

是性质相同的数据元素的集合,是数据的一个子集。(整数、字母和学籍表)
数据元素——组成数据的基本单位,是集合的个体;
数据对象——性质相同的数据元素的集合,是集合的子集。

2.2 数据结构(Data Structure)

数据在计算机内的存储往往存在着一种关系,数据元素之间的关系称为结构。那么数据结构就是指相互之间存在一种或多种特定关系的数据元素的集合(带结构的数据元素的集合)。

2.2.1 数据结构的三个内容

1.数据元素之间的逻辑关系,也称为逻辑结构;
2.数据元素及其关系在计算机内存中的表示(也称映像),称为数据的存储结构或物理结构;
3.数据的运算与实现:即对数据元素可以施加的操作以及这些操作在物理结构上的体现。

2.2.2 数据结构的两个层次

1.逻辑结构:①描述了数据元素之间的逻辑关系;②与物理结构无关,独立与计算机;③是从具体问题抽象出来的数学模型。
2.物理结构:①数据元素及其关系在计算机存储器中关系(存储方式);②是数据结构在计算机中的表示。
3.两者关系:①存储结构是逻辑关系的映像与元素本身的映像;②逻辑结构是数据结构的抽象,存储结构是数据结构的实现;③两者综合起来建立了数据元素之间的结构关系。

2.2.3 逻辑结构的种类

1.线性结构和非线性结构
线性结构:有且仅有一个开始和结尾结点,其余所有节点仅有一个直接前驱结点和一个直接后继结点。(线性表、栈、队列、串)
非线性结构:一个节点可能有多个前驱结点和后继节点。(图、树)
2.四种基本的逻辑结构
集合结构:结构中的数据元素之间除了同属于一个集合外,无其他任何关系;
线性结构:结构中的数据元素之间存在着一对一的线性关系;
树形结构:结构之间的数据元素之间存在着一对多的层次关系;
图状结构或网状结构;结构的数据元素之间存在着多对多的任意关系。
在这里插入图片描述

2.2.3 存储结构的种类

四种基本的存储结构:顺序存储、链式存储、索引存储、散列存储。
1.顺序存储:用一组连续的存储单元依次存储数据,数据元素之间的逻辑关系由元素的存储位置来表示。

2.链式存储:用一组任意的存储单元存储数据元素,数据元素之间的逻辑关系用指针来表示。

3.索引存储

4.散列存储

2.3 数据类型和抽象数据类型

高级语言中的数据类型规定了在程序执行期间变量的取值范围以及这些数值所允许进行的操作。(约束取值范围,约束操作)
一些基本的数据结构可以直接通过类型来实现(数组、字符串),而另一些常用的数据结构(栈、队列、树、图等),不能直接用数据类型来表示。

2.3.1 数据类型(Data Type)

定义:数据类型是一组相同性质的值的集合以及定义于这个值集合上的一组操作的总称(数据类型=值的集合+值集合上的一组操作)。

2.3.2 抽象数据类型(Abstract Data Type,ADT)

定义:从具体问题中抽象出的数学模型以及在此数学模型上的一组操作。
特点:①从具体问题抽象出的数学模型(逻辑结构);②包括定义在数学模型上的一组抽象运算(相关操作);③不考虑计算机内具体的存储结构以及运算算法的具体实现。
抽象数据类型的形式定义:可用(D,S,P)三元组表示。D表示数据对象,S是D上的关系集,P是对D的基本操作集。
在这里插入图片描述
基本操作的格式说明:
参数表:赋值参数:只为操作提供输入值;引用参数:以&开头,提供输入值,并返回操作结果(类似于C语言中的传址调用);
初始条件:描述操作之前数据结构与参数应该满足的条件;
操作结果:操作完成之后,数据结构的变化状况和应返回的结果。
在这里插入图片描述
举例1:复数的定义

ADT Complex{
    数据对象:D={r1,r2|r1,r2均为实数}
    数据关系:R={<r1,r2>|r1是实部,r2是虚部}
    基本操作:
    Assign(&C,v1,v2)
      初始条件:空的复数C已经存在
      操作结果:构造复数C,r1,r2的值为v1,v2
    Destroy(&C)
      初始条件:复数C存在
      操作结果:复数C已销毁
    GetReal(&C,&realPart)
      初始条件:复数C存在
      操作结果:用realPart返回复数C的实部值
     GetImag(&C,&imagPart)
      初始条件:复数C存在
      操作结果:用imagPart返回复数C的虚部值
      
}ADT Complex

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

顾名思义,将抽象数据类型在计算机上实现,变为一个能用的具体的数据类型。
例如:抽象数据类型复数的实现

typedef struct Complex
{
	float realPart;
	float imagPart;
};

void AssignComplex(Complex *p,float a,float b);
void AddComplex(Complex* p, Complex a, Complex b);
void SubComplex(Complex* p, Complex a, Complex b);
void MulComplex(Complex* p, Complex a, Complex b);
void DivComplex(Complex* p, Complex a, Complex b);
void ShowComplex(Complex p);

int main()
{
	Complex c1, c2, c3;
	AssignComplex(&c1, 1, 2);
	AssignComplex(&c2, 3, 4);
	AssignComplex(&c3, 5, 6);
	ShowComplex(c1);
	ShowComplex(c2);
	ShowComplex(c3);
	return 0;
}

void AssignComplex(Complex* p, float a, float b)
{
	assert(p != NULL);
	p->realPart = a;
	p->imagPart = b;
}

void AddComplex(Complex* p, Complex a, Complex b)
{
	assert(p != NULL);
	p->realPart = a.realPart + b.imagPart;
	p->imagPart = a.imagPart + b.imagPart;
}

void SubComplex(Complex* p, Complex a, Complex b)
{
	assert(p != NULL);
	p->realPart = a.realPart - b.imagPart;
	p->imagPart = a.imagPart - b.imagPart;
}

void MulComplex(Complex* p, Complex a, Complex b)
{
	assert(p != NULL);
	p->realPart = a.realPart * b.imagPart;
	p->imagPart = a.imagPart * b.imagPart;
}


void DivComplex(Complex* p, Complex a, Complex b)
{
	assert(p != NULL);
	p->realPart = a.realPart / b.imagPart;
	p->imagPart = a.imagPart / b.imagPart;
}

void ShowComplex(Complex p)
{
	printf("%f + %f", p.realPart, p.imagPart);
	printf("i \n");
}

3. 算法与算法分析

3.1 算法

算法的定义:解决问题的方法和步骤(对特定问题求解方法和步骤的一种描述,它是指令的有限序列。)
算法的描述:①自然语言:英文、中文;②流程图:传统流程图、NS程图;③伪代码:类C语言;④程序代码:C语言程序、JAVA语言程序。
算法与程序的关系:
算法是解决问题的一种方法或过程,一个问题可以有多种算法。
程序是用某种设计语言对算法的具体实现。
在这里插入图片描述
算法的特性:
①有穷性:算法的执行步骤是有限的,且每一步所需的时间都是有穷的;
②确定性:算法的每一条指令都有确切的含义,在任何条件下,只有唯一的执行路径,即对于相同的输入都能得到相同的输出;
③可行性:算法是可执行的,算法描述的操作可以实现;
④输入:一个算法有零个或多个输入;
⑤输出:一个算法有一个或多个输出。
算法设计的要求:
①正确性:程序对于精心选择的、典型的、苛刻且带有刁难性的几组结果能够得出满足要求的结果;
②可读性:算法应易于人的理解;
③健壮性:当输入非法数据时,算法能够恰当的作出反应而不是产生莫名其妙的输出结果(处理出错的方法,不应是程序停止执行,而应是返回一个表示错误或者错误性质的值);
④高效性:花费尽量少的时间和尽量低的存储需求。

3.1 算法分析

算法分析的目的:判断算法是否可行,并比较同一问题的多种算法的性能,以便从中挑选较优的算法。
算法的效率从以下两个方面来考虑:①时间效率:执行算法所耗费的时间;②空间效率:执行算法所耗费的存储空间。(时间效率和空间效率有时候是矛盾的)
算法效率的度量分为事后统计和事前分析。由于事后统计的结果依赖于计算机的软硬件等环境因素,因此我们使用事前分析来进行度量。

3.2 算法的时间复杂度

一个算法的运行时间大致可以等于计算机执行一种简单的操作(如赋值、比较、移动等)所需的时间与算法中进行简单操作次数的乘积。也就是每条语句的执行时间之和(每条语句的执行次数,又称语句频度)。
在这里插入图片描述
每条语句的执行时间,取决于机器的指令性能、速度以及编码的代码质量,由机器本身软硬件所决定,与算法无关。所以,我们假设执行每条语句所需的时间为单位时间,这样就可以独立于机器来分析算法性能了。
在这里插入图片描述
为了便于比较不同算法的效率,我们仅比较他们的数量级(所消耗的时间仅留下没有系数的最高次幂称为其数量级)。
在这里插入图片描述
在这里插入图片描述
算法中基本语句的执行次数是问题规模n的某个函数,算法的时间量度记作:T(n)=O(f(n))。它表示随着n的增大,算法执行时间的增长率和f(n) 的增长率相同,称为渐进时间复杂度。
在这里插入图片描述

3.2.1 分析时间复杂度的基本方法

定理:
在这里插入图片描述
基本方法:①找出语句频率最大的那条语句作为基本语句;②计算基本语句的频度得到问题规模n的某个函数f(n);③取数量级用“O”表示。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
注意:有的情况下,算法中基本操作重复执行的次数还随问题的输入集不同而不同。
例如:在数组中顺序查找为e的元素,那么最好的情况就是该元素在第一个位置,一次便找到;最坏的情况是该元素在最后一个位置,遍历了整个数组才找到。最好情况:1;最坏情况:n;平均时间复杂度:O(n)。

3.2.2 算法时间效率的比较

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3 算法的空间复杂度

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浮沉丿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值