数据结构可以说是计算机软件相关专业的基础课程,几乎可以说要想从事编程或开发工作,都无法避开这部分的知识。但是这部分知识也是相对来说较难的知识,即使是学会了其中的内容,要在开发和编程工作中很好地运用数据结构的知识对程序猿来说也是较难的,反正对我来讲是挺难的。在考研的过程中数据结构是我的一门主要的专业课,在那个时候可以说理解记忆并背诵了数据结构的每一个知识点,但那是相对于应试教育而言的,在实际的应用中我也发现光靠死记硬背是很吃力不讨好的。一年过去了,大部分概念已经遗忘,只有零碎的知识停留在脑海中,还是那句话好记性不如烂笔头,只不过这一次的烂笔头是我的键盘,通过这次的复习和代码练习,相信能对数据结构有更深入的了解,在实际应用中有更大的提升。
一、数据结构绪论
1、部分基础概念
数据结构:是相互之间存在的一种或多种特定关系的数据元素的集合。
数据:是描述客观事物的符号,是能被计算机识别并输入到计算机中处理的符号集合。
数据元素:是组成数据的、有一定意义的基本单位,在计算机当中通常作为整体处理。
数据项:一个数据元素由若干个数据项组成,是数据不可分割的最小单位。
数据对象:是性质相同的数据元素的集合。
按照视点的不同,我们把数据结构分为逻辑结构和物理结构。
2、逻辑结构:指数据对象中数据元素之间的相互关系。逻辑结构分为以下四种:
- 集合结构
- 线性结构
- 树形结构
- 图形结构
3、物理结构:指数据的逻辑结构在计算机中的存储形式、
数据的存储结构应正确反映数据元素之间的逻辑关系,这是最关键的。
数据元素的存储结构形式有两种:
1、顺序存储结构
是把数据元素存放在地址连续的存储单元里,其数据间的逻辑关系和物理关系是一致的。
2、链式存储结构
是把数据元素存放在任意的存储单元里,这组单元可以是连续的,也可以是不连续的。数据元素的村属关系并不能反映其逻辑关系,因此需要一个指针存放数据元素的地址,这样就可以灵活找到相关数据的位置。
4、抽象数据类型
数据类型:指一组性质相同的值的集合及定义在此集合上的一些操作的总称。
抽象数据类型(ADT):指一个数学模型及定义在该模型上的一组操作。
描述抽象数据类型的标准格式:
ADT 抽象数据类型名
Data
数据元素之间逻辑关系的定义
Operation
操作1
初始条件
操作描述结果
操作2
.......
操作n
.......
endADT
二、算法
算法:是解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。
算法的特性:
1、具有零个或多个输入,有一个或多个输出
2、有穷性
3.确定性
4.可行性
1、算法效率的度量方法
事后统计方法:主要是通过设计好的测试程序和数据利用计算机计时器对不同算法编制的程序的运行时间进行比较,从而确定算法效率的高低。但是缺陷明显不予采纳。
事前分析估计算法:在计算机程序编制前,依据统计方法对算法进行估算。
程序运行的时间依赖于算法的好坏和问题的输入规模。根据函数的渐进增长,判断一个算法的效率时,函数中的常数和其他次要项可以忽略,主要取决于最高阶项的阶数。
2、算法时间复杂度
定义:在进行算法分析时,语句总的执行次数T(n)是关于问题规模n的函数,进而分析 T(n)随n的变化情况并确定T(n)的数量级。算法的时间复杂度也就是算法的时间量度,记作:T(n)=O(f(n)) 。他表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称时间复杂度。这样用大写O( )来体现算法时间复杂度的记法,我们称之为大O记法。
推导大O阶方法
1、用常数1取代运行时间中的所有加法常数。
2、在修改后的运行次数函数中,只保留最高阶项。
3、如果最高阶项存在且不是1,则去除与这个项相乘的常数。
得到的结果就是大O阶。
常数阶:
int sum = 0,n = 100;
sun = (1+n)*n/2;
printf("%d",sum);
算法的运行次数函数是f(n)=3,但是没有最高阶项,所以时间复杂度为O(1)。
线性阶:
下面代码它的循环的时间复杂度为O(n),因为循环体中的代码要执行n次。
int i;
for(i = 0;i < n;i++)
{
/*时间复杂度为O(1)的程序步骤*/
}
对数阶:
int count = 1;
where(count < n)
{
count = couont * 2;
}
在上面的代码中count每次乘2,有多少个2相乘后大于n就会退出循环,由得到,所以得到这个循环的时间复杂度为O()。
平方阶:
int i,j;
for(i = 0;i < n; i++)
{
for(j = 0;j < n; j++0
{
/*时间复杂度为O(1)的程序步骤序列*/
}
}
内外循环的时间复杂度都为O(n),所以这段代码的时间复杂度为O(n^2),
如果外循环的循环次数改为m,时间复杂度就为O()。
常用的时间复杂度所耗费的时间从小到大依次是:
O(1)<O()<O(n)<O(n)<O(n^2)<O(n^3)<O()<O(n!)<O()
我们在写代码的时候,完全也可以用空间来换时间。
算法的空间复杂度通过计算算法所需的存储空间实现,算法空间复杂度的计算公式记作:S(n) = O(f(n)),其中n为问题规模,f(n)为语句关于n所占存储空间的函数。