数据结构笔记

数据元素 (Data Element) 数据的基本单位,在计算机程序中通常被作为一个整体进行考虑和处理。数据元素有时也被称为元素、结点、顶点、记录等。

数据项 (Data Item) 数据项是不可分割的、含有独立意义的最小数据单位,数据项有时也称为字段(Field)或域(Domain)。

数据结构 (Data Structure) 数据结构是相互之间存在一种或多种特定关系的数据元素的集合。

数据类型 (Data Type) 数据类型是高级程序设计语言中的概念,是数据的取值范围和对数据进行操作的总和。

数据逻辑结构 根据数据元素之间关系的不同特性,通常有4类基本数据结构:
(1) 集合(Set):该结构中的数据元素除了存在“同属于一个集合”的关系外,不存在任何其它关系。
(2) 线性结构(Linear Structure):该结构中的数据元素存在着一对一的关系。
(3) 树形结构(Tree Structure):该结构中的数据元素存在着一对多的关系。
(4) 图状结构(Graphic Structure):该结构中的数据元素存在着多对多的关系。

数据存储结构 数据的存储结构包括顺序存储结构和链式存储结构两种。

顺序存储结构(Sequence Storage Structure)是通过数据元素在计算机存储器中的相对位置来表示出数据元素的逻辑关系,一般把逻辑上相邻的数据元素存储在物理位置相邻的存储单元中。在C#语言中用数组来实现顺序存储结构。因为数组所分配的存储空间是连续的,所以数组天生就具有实现数据顺序存储结构的能力。链式存储结构(Linked Storage Structure)对逻辑上相邻的数据元素不要求其存储位置必须相邻。链式存储结构中的数据元素称为结点(Node),在结点中附设地址域(Address Domain)来存储与该结点相邻的结点的地址来实现结点间的逻辑关系。这个地址称为引用(Reference),这个地址域称为引用域(Reference Domain)。

算法 算法(Algorithm)是对某一特定类型的问题的求解步骤的一种描述,是指令的有限序列。

 

算法的特性

1、有穷性(Finity):一个算法总是在执行有穷步之后结束,即算法的执行时间是有限的。
2、确定性(Unambiguousness):算法的每一个步骤都必须有确切的含义,即无二义,并且对于相同的输入只能有相同的输出。
3、输入(Input):一个算法具有零个或多个输入。它即是在算法开始之前给出的量。这些输入是某数据结构中的数据对象。
4、 输出(Output):一个算法具有一个或多个输出,并且这些输出与输入之间存在着某种特定的关系。
5、 能行性(realizability):算法中的每一步都可以通过已经实现的基本运算的有限次运行来实现。

评价算法的标准

1、正确性(Correctness)。算法的执行结果应当满足预先规定的功能和性能的要求,这是评价一个算法的最重要也是最基本的标准。算法的正确性还包括对于输入、输出处理的明确而无歧义的描述。
2、可读性(Readability)。算法主要是为了人阅读和交流,其次才是机器的执行。所以,一个算法应当思路清晰、层次分明、简单明了、易读易懂。即使算法已转变成机器可执行的程序,也需要考虑人能较好地阅读理解。同时,一个可读性强的算法也有助于对算法中隐藏错误的排除和算法的移植。
3、健壮性(Robustness)。一个算法应该具有很强的容错能力,当输入不合法的数据时,算法应当能做适当的处理,使得不至于引起严重的后果。健壮性要求表明算法要全面细致地考虑所有可能出现的边界情况和异常情况,并对这些边界情况和异常情况做出妥善的处理,尽可能使算法没有意外的情况发生。
4、运行时间(Running Time)。运行时间是指算法在计算机上运行所花费的时间,它等于算法中每条语句执行时间的总和。对于同一个问题如果有多个算法可供选择,应尽可能选择执行时间短的算法。一般来说,执行时间越短,性能越好。
5、占用空间(Storage Space)。占用空间是指算法在计算机上存储所占用的存储空间,包括存储算法本身所占用的存储空间、算法的输入及输出数据所占用的存储空间和算法在运行过程中临时占用的存储空间。算法占用的存储空间是指算法执行过程中所需要的最大存储空间,对于一个问题如果有多个算法可供选择,应尽可能选择存储量需求低的算法。实际上,算法的时间效率和空间效率经常是一对矛盾,相互抵触。我们要根据问题的实际需要进行灵活的处理,有时需要牺牲空间来换取时间,有时需要牺牲时间来换取空间。

 

算法的时间复杂度

一个算法的时间复杂度(Time Complexity)是指该算法的运行时间与问题规模的对应关系。一个算法是由控制结构和原操作构成的,其执行的时间取决于二者的综合效果。为了便于比较同一问题的不同算法,通常把算法中基本操作重复执行的次数(频度)作为算法的时间复杂度。算法中的基本操作一般是指算法中最深层循环内的语句,因此,算法中基本操作语句的频度是问题规模n的某个函数f(n),记作:T(n)=O(f(n))。其中“O”表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,或者说,用“O”符号表示数量级的概念。例如,如)1n(n21)n(T−=,则 )1n(n21−的数量级与n2相同,所以T(n)=O(n2)。
如果一个算法没有循环语句,则算法中基本操作的执行频度与问题规模n无关,记作O(1),也称为常数阶。如果算法只有一个一重循环,则算法的基本操作的执行频度与问题规模n呈线性增大关系,记作O(n),也叫线性阶。常用的还有平方阶O(n2)、立方阶O(n3)、对数阶O(log2n)等。

 

1.6 分析下面语句段执行的时间复杂度。
(2) for (int i=0; i<n; ++i)
{
++p;
}

一重循环, 语句的频度为n,程序段的时间复杂度是T(n)=O(n)。


(3) for (int i<0; i<n; ++i)
{
for (int j =0; j<m; ++j)
{
++p;
}
}

二重循环,外层n,内层m,故程序段的时间复杂度是T(n)=O(m*n)。

 

(4) i = 1;
while(i <= n)
{
i *= 3;
}

一重循环, 语句的频度为n-1,程序段的时间复杂度是T(n)=O(n-1)=O(n)。


(5) int i = 1;
int k = 0;
do
{
k = k+10*i;
++i;
}

语句的频度为无穷,T(n)=O(无穷).

posted on 2008-12-05 14:24  杨斐  阅读(1176)  评论(0编辑  收藏  举报

导航