1.数据(Data)
数据是信息的载体。数据时对客观事物的逻辑归纳,是能够被计算机识别、存储和加工处理的数字、字符以及各种符号集合的统称,是计算机程序加工的“原料”。它可以是离散的数字、文字、符号等,也可以是连续的数据,如声音、图像等。
2. 数据元素(Data Element)
数据元素是组成数据的基本单位,也成为结点、顶点、记录等,在计算机程序中通常作为一个整体进行考虑和处理。一个数据元素可以是一个不可分割的原子项,也可以由若干个数据项组成。
3. 数据项(Data Item)
数据项是数据元素中具有独立含义的最小表示单位,为称为字段、域、属性。
4. 数据对象(Data Object)
数据对象时性质 相同的数据元素的集合,是数据的子集。性质相同指的是数据元素具有相同数量和类型的数据项。
5. 数据结构(Data Structure)
数据结构就是数据元素之间的相互关系,即数据的组织形式。
包含三个方面:数据的逻辑结构、数据的存储结构、数据的运算(操作或算法)。通常,算法的设计取决于数据的逻辑结构,算法的实现取决于数据的存储结构。
数据的逻辑结构常简称为数据结构,分为线性结构和非线性结构了两种,其中非线性结构又主要包括树结构和图结构。
1.线性结构
线性结构是数据元素之间具有线性关系的数据结构,数据元素之间形成一对一的关系。其特征是:除第一个和最后一个元素外,每个数据元素有且仅有一个直接前驱和一个直接后继元素,第一个元素只有一个直接后继元素,最后一个元素只有一个直接前驱元素。
2. 树结构
树结构是数据元素之间具有层次关系的一种非线性结构,数据元素之间存在一对多的关系,树中数据元素通常称为结点。其特征是:出来根节点和叶子结点之外,树中任意一个结点只有一个直接前驱结点(父结点)和多个直接后继结点(孩子结点),根结点没有前驱结点,叶子结点没有后继结点。
3. 图结构
图结构也是非线性结构,数据元素之间存在多对多的关系,每个数据元素可有多个前驱元素和多个后继元素。
4. 集合结构
集合结构中的数据元素除了属于同一个集合外,它们之间没有其他关系。各个数据是“平等”的,它们的共同关系就知识属于同一个集合,如图
数据的存储结构主要有两种:顺序存储和链式存储。为了加快查找速度,引入了索引(分块)查找和散列(哈希)查找。因此,从采用顺序存储和拉链式存储。
1.顺序存储结构是把数据元素依次放在一组地址连续的存储单元里,数据元素的物理存储次序和它们的逻辑次序相同,即逻辑上相邻的结点存储在物理位置上相邻的存储单元中。通常,使用程序设计语言中的数组来实现顺序存储结构。
2.链式存储结构
链式存储结构是把数据元素存放在任意的存储单元里,这组存储单元可以是连续的,也可以是不连续的,了逻辑上相邻的数据元素在物理位置上不一定相邻。通常,需要采用指针变量来记载前驱和后继元素的存储地址。
3.索引存储结构
除数据元素需要采用顺序存储或链式存储结构外,还要加你了附加的索引表来标识数据元素的地址。它不是独立的存储结构,只是为了在查找运算时,能够减少查找的时间,提高数据查找的性能。索引表中的每一项称为索引项,索引项由元素的关键字和它的存储地址组成,关键字是能够唯一标识一个数据元素的数据项
4. 散列(哈希)存储结构
散列存储结构根据结点的关键字直接计算出该结点的存储地址。它是一种能快速实现访问的存储方式,理想情况下,无须比较即可根据指定值直接定位记录的存储位置。
学习“数据结构”就必须认识“算法”。为什么呢?瑞士计算机科学家尼古拉斯- 沃斯 曾经提出:
程序=算法+数据结构
1.算法的概念
算法(Algorithm)是描述解决特定问题的思路、方法和步骤,是求解步骤(指令)的有限序列。
2. 算法的重要特性
1. 输入:一个算法应该有零个或多个输入。
2.有穷性:一个算法必须在执行有穷步骤之后正常结束,不能形成无穷循坏,并且每一个步骤都在可接受对的时间内完成,如果一个问题的求解算法需要10年的执行时间,尽管从数学角度看它是有穷的,可这个算法是没有任何意义的
3.确定性:算法中的每一条指令必须有确切的含义,不能产生多义性,即算法的每一个步骤被精确定义而无歧义,相同的输入只能有唯一的输出结果。
4.可行性:算法中的每一条指令必须是切实可执行的,即原则上可以通过已经实现的基本运算执行有限次来实现。算法可以转换为程序上机运行,并得到正确结果
5.输出:一个算法应该有一个或多个输出,这些输出是同输入,有某个特定关系的量
3. 算法和程序的关系
算法和程序都是用来表达解决问题的,逻辑步骤算法是对解决问题的方法的具体描述程序是用,某种程序设计与语言对算法的具体实现。
程序与算法最大的区别是程序可以是无穷的,而算法必须满足有穷性,即算法不允许无限循环。例如,操作系统是各个程序,这个程序在不遭破坏的情况下永远不会停止,即使没有作业需要处理,他仍处于一个等待循环中
一个算法可以用自然语言、流程图、伪代码来描述,也可以用高级程序设计语言,如Java、C、C++来描述。
1.自然语言
2.框图
3.伪代码
4.高级程序设计语言
同一个问题可以设计不同算法来解决,而一个算法的质量优劣直接影响到算法(程序)的效率。对算法进行分析和评价是为了选择合适的算法一级改进算法。
通常,算法设计应满足一下5个方面。
(1)正确性
(2)可读性
(3)健壮性
(4)时间高效性
(5)空间高效性
[注意]对于一个算法(或程序)效能的分析和评估,经常是从时间与空间两方面来考虑(时间复杂度和空间复杂度),尽量满足时间效率高和空间存储量低的需求。
2.时间复杂度
一个算法所耗费的时间,应迄具泫算法中每条语句的执行时间之和,而每条语句的执行时间是该语句的执行次为与该语句执行一次所需时间的乘积。但随着计算机硬件和软件技术的不断提升,一个算法的执行时间是无法精确计算的,只能进行估算。假设每条语句执行一次所需的时间均是单位时间,这样,一个算法的时间耗费就是该算法中所有语句的频度之和。
(1)O()函数
表示算法的时间效率与算法所处理的数据元素个数n(问题规模)的函数关系的最常用函数是O()函数。
一般情况下,算法的基本操作里夏执1的次数是问题规模n的某个函数f(n),则算法的时间复杂度 T(n)可记作。
T(n)=O(f(n))
它表示随着问题规模的扩大,算法执行时间的增长率和fn)的增长率相同。当n趋近于无穷大时,T(n/f(n)的极限值为不等于零的常数。O(f(n))称作算法的渐近时间复杂度,简称时间复杂度。
【例1-1】假设某算法运行时间为T(n)-4n3+3n2+9n,求它的时间复杂度。求解算法的时间复杂度分为3步:
① 去掉运行时间中的所有加法常数;
② 只保留最高阶项;
③ 去掉与这个最高阶相乘的常数。因此,该算法的时间复杂度为O(n3)。
(2)算法的时间复杂度分析
分析一个算法中基本语句的执行次数,可求出该算法的时间复杂度。【例1-2】分析下列程序段的时间复杂度。
public static void main(String[] args){
int n=100,sum=0; //(1)赋初值
for (int i=1;i<=n;i++){
sum=sum+i; //(2)累加和
}
System.out.println (sum) ;
}
(2)算法的时间复杂度分析
分析一个算法中基本语句的执行次数,可求出该算法的时间复杂度。【例1-2】分析下列程序段的时间复杂度。
public static void main(String[] args){
int n=100,sum=0;//(1)赋初值for (int i=1;i<=n;i++){
sum=sum+i;
//(2)累加和
}
System.out.println (sum) ;
该算法的规模为n,基本操作语句是累加和“sum=sum+i;”,它在循环中的执行次数为n次,因此时间复杂度为O(n)。