数据结构与算法分析(一)

数据结构与算法分析(一)

数据结构 + 算法 = 程序
数据结构主要研究组织大量数据的方法,算法分析是对算法运行的时间的评估。

第一章 基本概念

第一节 数据结构

1.1 基本术语和概念

(1)数据(Data):是指描述客观事物的符号,是计算机可以操作的对象,能被计算机识别,并输入给计算机处理的符号或符号集合。万物皆可为数据,不止局限于数字,字符,一个图像,一段视频都是数据。

(2)数据对象(data object):是性质相同数据元素的集合,是数据的一个子集。例如所有的视频数据可以成为一个数据对象。

(3)数据元素(data element):是数据的基本单位。也叫结点或记录。例如一个视频。

(4)数据项(data item):是数据的最小单位。例如视频里的每一帧。

(5)数据结构(data structure):是数据元素之间的组织方式。

1.2. 数据的逻辑结构

逻辑结构(logical structure):指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前后件关系,而与他们在计算机中的存储位置无关。

数据结构有四种不同的逻辑结构:

(1)集合结构:集合中的各个元素是平等的,元素之间没有任何联系,仅是共处于同一集合。

(2)线性结构:元素结构关系是一对一的,并且是一种先后的次序。

(3)树形结构:元素结构关系是一对多的,并且存在父子级。

(4)图形结构:元素结构关系是多对多的。

1.3 数据的存储结构

存储结构(storage structure) 也成为物理结构(physical structure),是指数据的逻辑结构在计算机中的存储形式,一般可以反映数据元素之间的逻辑关系。

数据结构有两种不同的存储结构:

(1)顺序存储结构:把数据元素存储在地址连续的存储单元中,数据间的逻辑关系和物理关系是一致的。

(2)链式存储结构:把数据元素存储在任意的存储单元里,这组存储单元可以是连续的,也可以是不连续的。

1.4 抽象数据类型

抽象数据类型(abstract data type,ADT) 是一些操作的集合。描述数据类型的方法不依赖于具体实现,与存放的机器无关,与数据存储的物理结构无关,与实现操作的算法和编程语言无关,只描述数据对象集合相关操作集“是什么”,并不干涉“如何做到”。

表ADT 栈ADT 队列ADT

第二节 算法及性能分析

2.1 算法

算法(algorithm) 是一系列为特定问题而规定指令的集合。有以下特性:

  • 输入,是指算法具有零个或多个输入。

  • 输出,是指算法至少有一个或多个输出。

  • 有穷性,是指算法在执行有限的步骤之后,自动结束而不是出现无限循环,并且每一个步骤在可接受的时间内完成。

  • 确定性,是指相同输入只能有一个唯一的输出结果,不会出现二义性。

  • 可行性,是指算法每一步骤都必须可行,能够通过有限的执行次数完成。

2.2时间复杂度

​ 算法的时间复杂度,也就是算法的时间量度,记作: T(n)=O(f(n))。它表示随问题规模 n的增大算法执行时间的增长率和 f(n)的增长率相同,称作算法的渐进时间复杂度,简称为时间复杂度。其中 f(n)是问题规模 n的某个函数。

2.2.1计算方法:

1.用常数1取代函数中所有的常数

2.只保留最高项

3.最好情况时间复杂度:代码在最坏情况下执行的时间复杂度。

常用的时间复杂度所耗费的时间从小到大依次是

  • O(1) < O(log n) < O(n) < O(nlog n) < O(n2) < O(n3) < O(n!) < O(nn)
2.2.2 一般法则

法则 1-----for循环

一次for循环的运行时间至多是该for循环内语句的运行时间X循环的次数。

for(i = 1 ; i <= n ; i++)
{
    x = x + 1;		/* 时间复杂度为O(n) */
}

法则 2-----嵌套的for循环

从里向外分析,在一组嵌套循环内部的一跳语句总的运行时间为该语句的运行时间X该组所有for循环的大小的乘积。

for( i = 0; i < n; i++)
{
    for(j = 0; j < n; j++)
        k++;		/* 时间复杂度为O(n*n) */
}

法则 3-----顺序语句

将各个语句的运行时间求和即可,其中的最大值即为运行时间。

for(i = 1 ; i <= n ; i++)
{
    x = x + 1;		/* 时间复杂度为O(n) */
}
for( i = 0; i < n; i++)
{
    for(j = 0; j < n; j++)
        k++;		/* 时间复杂度为O(n*n) */
}
/* 总时间复杂度为O(n*n) */

法则 4-----while语句

int count = 1;
while(count < n){
	count *= 2;
	/*时间复杂度为 O(1) 的程序步骤序列*/
}

/* 2^x = n  时间复杂度为O(log n) */
2.3 空间复杂度

算法的空间复杂度是通过计算算法所需的存储空间实现,算法空间复杂度的计算公式记作: S(n)=O(f(n))S(n)=O(f(n)) S(n) = O(f(n))S(n)=O(f(n)) 。其中,n 为问题的规模, f(n)f(n) f(n)f(n) 为语句关于 n 所占存储空间的函数。

2.4 递归:
int F(int x)
{
    if(x == 0)
        retuen 0;
    else 
        return 2 * F(x-1) + X * X;
}
1.它是否就是循环逻辑?

答案是:虽然函数会用到这个函数本身,但是我们并没有用函数本身来定义函数的一个特定的实例。即使用F(5)来得到F(5)的值才是循环,通过F(4)来得到F(5)的值不是循环的。

2.实现递归的基本准则:

基准情形:递归中必须要有某些基准情形,他们不用递归就能求解。

不断推进:对于那些需要递归求解的情形,递归调用必须总能朝着产生基准情形的方向推进。

设计法则:假设所有的递归调用都能运行。

合成效益法则:在求解一个问题的同一实例时,切勿在不同的递归调用中做重复性的工作。

  • 11
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构:⼋⼤数据结构分析 数据结构分类 数据结构是指相互之间存在着⼀种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成 。 常⽤的数据结构有:数组,栈,链表,队列,树,图,堆,散列表等,如图所⽰: 线性表和⾮线性表 ⼀、线性表 常见的线性表有:数组、队列、栈、链表 线性表是最基本、最简单、也是最常⽤的⼀种数据结构。线性表(linear list)是数据结构的⼀种,线性表就是数据排列成⼀条先⼀样的结 构,每个线性表上的数据最多只有前和后两个⽅向。⼀个线性表是n个具有相同特性的数据元素的有限序列。 特点: 1. 集合中必存在唯⼀的⼀个"第⼀元素"。 2. 集合中必存在唯⼀的⼀个 "最后元素" 。 3. 除最后⼀个元素之外,均有唯⼀的后继(后件)。 4. 除第⼀个元素之外,均有唯⼀的前驱(前件)。 顺序表⾥⾯元素的地址是连续的;链表⾥⾯节点的地址不是连续的,是通过指针连起来的。 1.数组 数组是可以再内存中连续存储多个元素的结构,在内存中的分配也是连续的,数组中的元素通过数组下标进⾏访问,数组下标从0开始。例 如下⾯这段代码就是将数组的第⼀个元素赋值为 1。 int[] data = new int[100];data[0] = 1; 优点: 1、按照索引查询元素速度快 2、按照索引遍历数组⽅便 缺点: 1、数组的⼤⼩固定后就⽆法扩容了 2、数组只能存储⼀种类型的数据 3、添加,删除的操作慢,因为要移动其他的元素。 适⽤场景: 频繁查询,对存储空间要求不⼤,很少增加和删除的情况。 2.栈 栈是⼀种特殊的线性表,仅能在线性表的⼀端操作,栈顶允许操作,栈底不允许操作。 栈的特点是:先进后出,或者说是后进先出,从栈 顶放⼊元素的操作叫⼊栈,取出元素叫出栈。 栈的结构就像⼀个集装箱,越先放进去的东西越晚才能拿出来,所以,栈常应⽤于实现递归功能⽅⾯的场景,例如斐波那契数列。 3.队列 队列与栈⼀样,也是⼀种线性表,不同的是,队列可以在⼀端添加元素,在另⼀端取出元素,也就是:先进先出。从⼀端放⼊元素的操作称 为⼊队,取出元素为出队,⽰例图如下: 使⽤场景:因为队列先进先出的特点,在多线程阻塞队列管理中⾮常适 ⽤。 4.链表 链表是物理存储单元上⾮连续的、⾮顺序的存储结构,数据元素的逻辑顺序是通过链表的指针地址实现,每个元素包含两个结点,⼀个是存 储元素的数据域 (内存空间),另⼀个是指向下⼀个结点地址的指针域。根据指针的指向,链表能形成不同的结构,例如单链表,双向链表, 循环链表等。 链表的优点: 1. 链表是很常⽤的⼀种数据结构,不需要初始化容量,可以任意加减元素; 2. 添加或者删除元素时只需要改变前后两个元素结点的指针域指向地址即可,所以添加,删除很快; 缺点: 1. 因为含有⼤量的指针域,占⽤空间较⼤; 2. 查找元素需要遍历链表来查找,⾮常耗时。 适⽤场景: 数据量较⼩,需要频繁增加,删除操作的场景 ⼆、⾮线性表 常见的⾮线性表有:树、图、堆 ⾮线性表中数据并不是简单的前后关系。 1.树 树是⼀种数据结构,它是由n(n>=1)个有限节点组成⼀个具有层次关系的集合。把它叫做 "树" 是因为它看起来像⼀棵倒挂的树,也就 是说它是根朝上,⽽叶朝下的。它具有以下的特点: 每个节点有零个或多个⼦节点; 没有⽗节点的节点称为根节点; 每⼀个⾮根节点有且只有⼀个⽗节点; 除了根节点外,每个⼦节点可以分为多个不相交的⼦树; 在⽇常的应⽤中,我们讨论和⽤的更多的是树的其中⼀种结构,就是⼆叉树。 ⼆叉树是树的特殊⼀种,具有如下特点: 每个结点最多有两颗⼦树,结点的度最⼤为2。 左⼦树和右⼦树是有顺序的,次序不能颠倒。 即使某结点只有⼀个⼦树,也要区分左右⼦树。 ⼆叉树是⼀种⽐较有⽤的折中⽅案,它添加,删除元素都很快,并且在查找⽅⾯也有很多的算法优化,所以,⼆叉树既有链表的好处,也有 数组的好处,是两者的优化⽅案,在处理⼤批量的动态数据⽅⾯⾮常有⽤。 2.散列表 散列表,也叫哈希表,是根据关键码和值 (key和value) 直接进⾏访问的数据结构,通过key和value来映射到集合中的⼀个位置,这样就可 以很快找到集合中的对应元素。 记录的存储位置=f(key) 这⾥的对应关系 f 成为散列函数,⼜称为哈希 (hash函数),⽽散列表就是把Key通过哈希函数转换成⼀个整型数字,然后就将该数字对数 组长度进⾏取余,取余结果就当作数组的下标,将value存储在以该数字为下标的数组空间⾥,这块连续存储空间称为散列表或哈希表 (Hash table),这种存储空间可以充分利⽤数组的查找优势来查找元素,所以查找的速度很快。 散列数据结构的性能取决于以下三个因素: 哈希函数 哈希表的⼤⼩ 碰撞处理⽅法 哈希表在应⽤中也是⽐较常见的,就如Java中有些集合类

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值