两个问题:
1. 为什么要学习数据结构?
早起人们把计算机理解为数值计算工具,就是感觉计算机当然是用来计算的,所以计算机解决问题,应该先从具体问题中抽象出一个适当的数据模型,设计出一个解此数据模型的算法,然后再编写程序,得到一个实际的软件。
可现实中,我们更多地不是解决数值计算的问题,而是需要一些更科学有效的手段(比如表、树、图等数据结构)的帮助,才能更好地处理问题。所以
数据结构是一门研究非数值计算的程序设计问题中的操作对象,以及它们之间的关系和操作等相关问题的学科。
2. 要学到什么程度?
在工作中发现,我们所需要的栈、队列、链表、散列表等结构,以及查找、排序等算法,在编程语言的开发包中都有完美的实现,我只需要掌握如何使用他们就可以了,为什么还要去弄懂这里面的算法原理呢?
答:一定要弄懂这里面的算法原理,并且能够利用核心的算法思想解决实际问题。
相关概念定义:
数据结构:
是相互之间存在一种或多种特定关系的数据元素的集合。
数据结构分类:逻辑结构(集合结构、线性结构、树形结构、图形结构)和物理结构(也就是存储结构,指数据的逻辑结构在计算机中的存储形式)
数据元素的物理结构分为:顺序存储结构和链式存储结构两种。
逻辑结构是面向问题的,而物理结构是面向计算机的,其基本的目标就是将数据及其逻辑关系存储到计算机的内存中。
注:物理结构的定义,实际上就是如何把数据元素存储到计算机的存储器中。存储器主要是针对内存而言的,像硬盘、软盘、光盘等外部存储器的数据组织通常用文件结构来描述。
数据类型与抽象数据类型
数据类型:指一组性质相同的值的集合以及定义在此集合上的一些操作的总称。
在 C 语言中,按照取值的不同,数据类型可以分为两类:
原子类型:是不可以再分解的基本类型,包括整型、实型和字符型。
结构类型:由若干个类型组合而成,是可以再分解的。例如,整型数组是有若干个整型数据组成的。
抽象数据类型:Abstract Data Type,ADT 是指一个数学模型及定义在该模型上的一组操作。抽象数据类型的定义仅取决于它的一组逻辑特性,而与其在计算机内部如何表示和实现无关。
算法
算法是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或者多个操作。
算法的五个基本特征:输入输出、又穷性、确定性、可行性。
好算法的特性:
1. 正确性
算法程序没有语法错误
算法程序对于合法的输入数据能够产生满足要求的输出结果
算法程序对于非法的输入数据能够得出满足规格说明的结果
算法程序对于精心选择的,甚至刁难测试数据都有满足要求的输出结果
2. 可读性
算法设计的另一目的便是为了便于阅读、理解和交流。
3. 健壮性
当输入数据不合法时,算法也能做出相关处理,而不是产生异常或者莫名其妙的结果
4. 时间效率高和存储量低
算法效率的度量方法
1. 事后统计法:这种方法主要是通过设计好的测试程序和数据,利用计算机计时器对不同算法编制的程序的运行时间进行比较,从而确定算法效率的高低。
注:因为这种方式存在太多弊端,比如说实现需要编号程序,耗时耗力,或者在不同的计算机上测试结果不一样,同一台计算机上cpu、内存的使用情况不一样也不同,另外算法的测试数据设计起来非常困难。
2. 事前分析估算方法:在计算机程序编制前,依据统计方法对算法进行估算。
2.1 算法采用的策略、方法(算法好坏的根本)
2.2 编译产生的代码质量(需要软件支持)
2.3 问题的输入规模
2.4 机器执行指令的速度(硬件性能决定)
抛开所有的与计算机硬件、软件有关的因素,一个程序的运行时间,依赖于算法的好坏和问题的输入规模,即 1 和 3 来决定。
不计那些循环索引的递增和循环终止条件、变量声明、打印结果等操作,最终,在分析程序的运行时间时,最重要的是把程序看成是独立于程序设计语言的算法或一系列步骤。
最终把 基本操作的数量表示成输入规模的函数。
结论:判断一个算法的效率时,函数中的常数和其他次要项常常可以忽略,而更应该关注主项(最高阶项)的阶数。
时间复杂度和空间复杂度
一般情况下,时间复杂度(即大O)指的是最坏时间复杂度的情况。
时间复杂度是我们在算法学习过程中经常要讨论的问题,用以评价算法的优劣。