大话数据结构学习记录

第二章 算法

1 讲算法更好的理解数据结构,相辅相成的关系

2 算法提高计算效率,那些公式是很必要的,是重要算法

算法定义:解决特定问题求解步骤的描述,在计算机中表现为指令的有限序列,并且每条指令表示一个或多个操作。

五个基本特征:输入,输出,有穷性,确定性和可行性

2.6 算法设计要求:

1 正确性:
无语法错误;
合法输入有满足要求输出;
非法输入有满足规格说明输出;
对于精心选择甚至刁难的数据有满足要求的输出结果

算法一般无法用程序证明,而是用数学方法证明,代价昂贵;一般到第三层次就可以了。

2 可读性
便于阅读、理解和交流

3 健壮性
当输入数据不合法时,算法也能做相关处理,而不是产生一场或者莫名其妙的结果

4 时间效率高和存储量低

2.7 算法效率的度量方法

1 事后统计
先写好算法,测试,统计时间

2 事前分析评估

消耗时间取决于四个因素:
1 算法采用的策略、方法;
2 编译产生的代码质量; 软件支持
3 问题的输入规模;
4 机器执行指令的速度 硬件性能

刨去软硬件因素,一个程序的运行时间取决于,算法的好坏和问题的输入规模

2.8 函数的渐进增长:增长趋势,忽略小量输入

对于给定的两个函数f(n) 和g(n),如果存在一个整数N,使得对所有的n>N,f(n) 总是比g(n)大,那么我们说f(n) 的增长渐进快于g(n)

2.9 时间量度

T(n) =O(f(n)) 随着问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称时间复杂度。 O(1)常数阶,线性阶,平方阶,对数阶(比如二分法)
这里写图片描述

2.11 最坏情况和平均情况

最坏情况运行时间是一种保证,那就是运行时间将不会再坏了,通常我们提到的运行时间都是最坏情况的运行时间。

平均运行时间是所有情况中最有意义的,因为它是期望的运行时间。

2.12 算法空间复杂度

这里写图片描述
存储程序本身的 指令、常数、变量、和输入数据、 还需要存储对数据操作的存储单元。 后面这个可能是指 临时存储

第三章 线性表 List “表”

零个或多个数据元素的有限序列:序列(前驱和后继)、有限

在较复杂的线性表中, 一个数据元素可以由若干个数据项组成。

  • 基本操作: 初始化,判断是否为空,清空,获取/定位,删除/插入,长度

  • 其他复杂操作可以由这些基本操作组合而成

3.4 顺序存储结构

定义:用一段地址连续的存储单元依次存储线性表的数据元素

顺序存储结构需要三个属性:
- 存储空间起始位置:数组data的存储位置
- 最大存储容量: 数组的长度 Maxsize
- 线性表当前长度:length

由于存储位置是编号的,连续的,我们对每个线性表位置的存入或者取出数据,对于计算来说都是相等的时间,

存取时间性能为O(1). 我们把这种存储结构称为随即存储结构。

  • 插入/删除时间复杂度O(n)

比较适合元素个数不太变化,存取数据的应用

这里写图片描述

3.6 线性表的链式存储结构

这里写图片描述
除了存储数据元素信息,还要存储它后继元素的存储地址,即 逻辑关系。

  • 我们把存储数据元素的域称为数据域,把存储直接后继位置的域称为指针域。
  • 指针域中存储的信息称作 指针 或链 ;
  • 这两部分信息组成数据元素的存储映像,称为节点(Node).

  • 第一个节点的存储位置称为头指针;最后一个节点指针为空。
    这里写图片描述

为了方便,常在第一个结点前附设一个结点,称为头结点。

3.7 单链表的读取

获取第i个元素 就是从头开始找; O(n)

3.8 单链表的插入和删除

3.9 单链表的创建

一个动态生成链表的过程,从空表的初始状态起,依次建立各元素节点
有两种方式:头插法和尾插法

3.10 单链表的整表删除

这里写图片描述
经验性结论:
- 若线性表需要频繁查找,很少需要插入和删除是,宜采用顺序存储结构,反之用单链表结构;

  • 当线性表中元素个数变化较大或者根本不知道有多大是,最好用单链表

3.12 静态链表

有些语言没有指针,该怎么实现链表呢?

用数组实的现: 数组的元素有两个数据域组成,data和cul,cul相当于单链表中的next指针,存放该元素大的后继在数组中的下标

这种用数组描述的链表叫做静态链表,游标实现法。!!!

3.13 循环链表

对于单链表,每个结点存储了向后的指针,前驱结点找不到

* 将单链表中终端结点的指针端由空指针改为头指针,整个链表就形成一个环* 循环链表

判断条件,p - next 不等于头结点,则循环未结束

用尾指针表示循环列表,这样查找头指针和终端指针都很方便,这样也很方便两个链表的合并

3.14 双向链表

在单链表的每个结点中,再设置一个指向其前驱结点的指针域

第四章 栈与队列

* 栈 限定 仅在 表尾 进行插入和删除操作的线性表*

* 队列 只允许 在一段进行插入操作 另一端进行删除操作的线性表*

4.2 栈的定义

允许插入和删除的一端称为栈顶 top ,另一端称为 栈底 bottom : 先进后出的线性表 Last in First out LIFO

插入: 进栈 压栈 入栈
删除: 出栈 弹栈

栈:stack
插入:push ;弹出:pop 特殊 不同于单链表

由于栈本身是一个线性表,那么前面讨论的线性表的顺序存储和链式存储 也是适用的

4.4 栈的顺序存储结构及实现

顺序栈,定义一个top 变量来指示栈顶元素在数组中的位置 空栈 top = -1 数组首元素为0

进栈和出栈 操作都挺简单,时间复杂度O(1)

4.5 两栈共享空间

因为当空间不够用时,数组的扩展很麻烦;

定义一个数组, 里面存储两个类型相同的栈

top1和top2 是栈1和栈2的栈顶指针,可以想象只要它两不见面,两个栈可以一直使用。

top1 +1 = top2 时为栈满。

通常是当两个栈的空间需求有相反关系时使用,比如股票买卖,一方出,一方进。

4.6 栈的链式存储结构及实现

链栈
链表有头指针,栈顶指针也是必须的,可以把栈顶放在单链表的头部,对于链栈来说,是不需要头结点的。

* 不存在栈满的情况,链栈为空就是top = NULL *

链栈的操作绝大部分和单链表类似,只是在插入和删除上特殊一些

push 和 pop 操作都很简单,没有任何循环操作,时间复杂度均为 O(1)

* 对比: *

顺序栈存取是定位方便,但是可能存在空间浪费;链栈要求每个元素都要有指针域,也会增加内存开销,长度无限制。

4.7 栈的作用

引入简化了程序设计的问题,划分了不同关注层次,使得思考范围缩小,更加聚焦于我们要解决问题的可信,如果总是使用素族,要分散精力去考虑数组的下标增减等细节问题,反而容易掩盖问题的本质。 高级语言都有栈结构的封装,可以直接使用。

注:这里提到的观点,是我学习中一直存在的问题,过于关注原理,而不是聚焦于问题的解决,容易拖延进度和受挫,毕竟还没有到真正天才的地步。 不管怎样站在前人肩膀上都是不错的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值