数据结构第二版重点知识内容1(补)-陈越

第一章:概述(补)

    • (1)clock()函数
    • (2)数据结构的分类与联系
    • (3)抽象数据类型
    • (4)算法

(1)clock()函数

 clock函数简介:使用clock函数需要添加头文件。clock函数可以捕捉从程序开始运行到clock函数被调用所耗费的实际,简言之就是函数会返回一个衡量时间的数,这个时间是从程序开始运行到函数开始调用这段时间。

#include //展示:引入头文件
clock();		 //clock函数

 clock函数详解:clock函数返回值类型为clock_t,为“时钟打点”,引入的头文件中还包含一个常量CLK_TCK,为机器时钟每秒所走的时钟打点数。所以要记录返回值则需定义clock_t变量记录,要转换为单位秒的时间需要除以CLK_TCK。

clock_t start,stop;//申请两个clock_t类型的变量
CLK_TCK;	       //CLK_TCK常量,可直接使用

 clock函数的运用:计算一段代码块的运行时间。即在代码块之前和之后分别使用clock函数,并且使用两个不同的clock_t类型变量记住返回值,则代码块运行时间为(代码块之后的变量-代码块之前的变量)/CLK_TCK。特殊的,clock_t实际为长整型(在头文件中重命名的),所以由于二者之差非常小除以CLK_TCK之前需要转换为double类型(否则很容易为0,如1/2)。

#include
#include 
int main()
{
     
	clock_t start,stop;//申请两个clock_t类型的变量
	start=clock();//一个在预测试代码块的上方记录从程序运行开始到此的时间
	for(int i=0;i<=999;i++)//预测试代码块
		printf("Hello world!");
	stop=clock();//另一个变量在预测试代码块下方,记录程序开始到此的时间
	printf("\n%lf",(double)(stop-start)/CLK_TCK);//计算并输入代码块运行时间
	return 0; 
}

详解计时函数链接

(2)数据结构的分类与联系

 数据结构的分类:

数据结构
逻辑结构          物理结构
线性 树 图 集合       顺序存储 链式存储

 逻辑结构:指数据集合中数据元素之间存在的逻辑关系。
 物理结构:指数据存储于计算机中的物理上的存储关系。
  线性逻辑结构:即数据中的元素之间存在线性的关系,即一对一。如排队是线性的,本质是每一个元素有且仅有一个前驱和一个后继(除了首尾),即一 一对应的逻辑关系。
  树状逻辑结构:即数据中的元素是存在一对多的关系。如果家族中的族谱,父母可能存在多个孩子,就需要建立一对多的关系。本质是一个元素仅有一个前驱,但可以有多个后继(仅有一个父母,但可以有多个孩子)。
  图状逻辑结构:即数据中的元素是存在多对多的关系。比如交通路线图中的每一个路口,可能通往多条路(多个后继),也可能被多条路通向自己(多个前驱),本质为多对多的逻辑关系。
  线性存储结构:即逻辑上相关的元素,存储于计算机中的位置也是相邻的。比如将一个排队队列输入一个数组,线性逻辑关系成立的两个人在数组中也是相邻的,由数组知识可知,他们在计算机存储中的存储单元也是相邻的,所以是线性存储。
  链式存储结构:即逻辑上相关的元素,存储于计算机中的位置是不相邻的。如我们学习过的链表,相邻链表节点直接存在线性关系(前驱与后继),但是他们存储的内存单元是随便分配的,常常是不相邻的。

(3)抽象数据类型

 概念:抽象数据类型(Abstract Data Type)是一种对“数据类型”的描述,这种描述是“抽象”的。
 抽象数据类型就是一种描述,对数据类型的描述。描述有两方面:一是数据对象集,二是与数据集合相关联的操作集。
 解释:我们说数据结构就是用来存储和组织数据元素的,它研究的是数据元素的逻辑结构和物理结构,但这些都涉及了数据元素,所以数据元素是什么样的,也是我们讨论数据结构的中必须讨论的。如果是在实现数据结构时必须要考虑到具体的数据对象的实现,而如果只是在理论学习时我们只需要讨论抽象的数据对象就可以了(这种抽象的数据对象统称为抽象数据类型,表示一种“暂时未确定实现"数据类型)。
 举例说明:如我们在讨论一个队列的数据结构时,数据元素就是队列中的每一个单元(比如人,货物),而他们的逻辑关系我们可以确定,就是相邻的元素间存在前驱或者后继的关系,但是物理结构呢?物理结构可以是顺序存储,如使用数组就是一种顺序存储,再如使用链表,就是链式存储。而且对于每个元素来说,其中存储的信息是什么?每个单元可以是数值(如商品的编码),又可以是字符串(如人排队信息为人名)。
 所以我们可以知道,在讨论一种数据结构时,针对不同的实际应用,其数据元素要求的类型是不同的,而我们要谈论的是理论的数据结构,所以我们最开始就要把不同的数据元素种类抽象为一种类型相同的类型,并且不用细致考虑很多实现,这就是抽象数据类型。抽象数据类型,探讨一些固定的属性和性质(对象集),探讨一些对其数据元素的理论操作(操作集)。

(4)算法

 算法是一个有限指令集,它接受或者不接受输入,但一定会产生输出(输出可以是任何形式的,总之就是要对外界有所反馈,不单单指printf的输出)。
 算法的表示:代码、伪代码、自然语言。相对于有限指令集,伪代码和自然语言更加容易理解,但无论是哪种形式,都是必须有确切的含义的(即不可有二义性),并且满足算法的要求。
 算法的时间复杂度与空间复杂度:算法常常会有输入,对于输入规模为n的算法,设其使用的空间大小为F(n),设其执行的基本语句次数为G(n),则算法的空间复杂度表示为O( F(n) ),则算法的时间复杂度表示为O( G(n) )。O符号表示函数的上界,即只取函数中增长最快的项(次方最大的项),并且将系数化为1。
 研究算法的意义:研究算法常常是为了解决问题,研究算法就是找解决问题的方法,研究解决问题的方法。算法的时间复杂度和空间复杂度从两个角度上说明了一个算法的性能,好的算法与不适合的简单算法的效率可能天差地别(比如计算1到n的正整数的和,当n取很大时循环单次累加很慢,但如果使用等差数量求和公式只需要计算一次就可得到结果)。

 代码实例:

#include
int main()
{
     
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		if(i==n)printf("%d ",i);
	for(int i=1;i<=n;i*=2)
		if(i*2>=n)printf("%d ",i);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if((i==n)&&(j==n))printf("%d",i*j);
	return 0; 
}

 这里的输入就是n,n的大小取值就是输入的规模。现在分析算法的空间复杂度,使用空间的有变量n,i,j。但是我们可以发现无论n输入多大,n,i,j所占空间不变(仍为三个整型),其所占空间为 3sizeof(int),所以其空间复杂度为O(3sizeof(int),取最大次方,这里表达式最高次方是零次方即常数项,再将常数项系数(即其自身)化为1,的其空间复杂度为O(1)。

 对于时间复杂度,分析基本语句执行次数,int n和scanf是两次,第一个for循环是n+1 +n +1 +n +1(i是否小于等于n判断了n+1次,i加了n次,int i定义了一次,i==n判断了n次,printf输出仅当满足情况时执行了1次)。共3n+3次。

 同理第二个循环,需要注意的是i从1每次乘以2,设12^x>=n则x=log2n,则乘了log2 n次,判断了log2n +1,则其总次数为log2n+log2n+1 +1+log2n+1。
共3
log2n+3次。

 最后一个循环先最看外层,定义i1次,判断i小于等于n有n+1次,i++有n次,再看次内层,定义j有n次(每一个i即每一次外层for循环都会创建一个j),判断j小于等于n有n*(n+1)次(每一个内层循环判断n+1次,外层n个i,一个i一个内层循环,所以判断n*(n+1)次 )。
 同理j++有n*(n)次,最内层if判断了nn次,输出printf了一次。1+n+1+n+n+n(n+1)+n2+nn+1共2*n^2+6n+3次。

 所以此算法的时间复杂度O(T)=O(3n+3 + 3log2n+3 + 2n^2+6n+3)=O(2nn)=O( n*n )。

补-最大子列和

你可能感兴趣的:(数据结构,c语言,数据结构,算法,程序设计)