bags,stack,queue

data type:
value : collections of object(存储对象方式不外乎:Array和list)
operation:add remove iterate isempty
不同的数据类型具有不同的特性:比如说,Stack 后进先出 queue先进先出
在这里插入图片描述
modular programming:
分离实现和接口 客户不知实现的细节,通过接口来复用基本操作;实现不需要考虑客户的需求,只是完成基本的操作
在这里插入图片描述Stack:
接口:
在这里插入图片描述实现:(实现数据类型,就是完成类型所支持的操作)
1、使用linklist实现Stack:
linklist的实现借助于内部类Node,Stack类定义一个栈顶指针,针对linklist来实现push、pop操作
在这里插入图片描述使用linklist的Stack的性能分析:
运行时间的分析:push、pop操作都很高效,running time is constant time;
内存分析:(内存分析这块视频还需要看看 包括教授讲的这几句话没太理解)
在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述2、使用array实现Stack
由于Stack有可能在一些循环中被使用到,因此对于linklist的效率仍存在质疑,希望stack实现可以更高效。使用Array 存储Stack的元素可以实现这个目的!但是在设计数据类型时,凡是使用数组来存储元素都会有一个问题:需要提前确定数组的大小。先从确定大小的Array 入手实现Stack ,之后再来修改!
在这里插入图片描述在下面的实现代码中,存在几个问题:需要指定数组大小;栈满却还在做push,数组越界;栈空却还在做pop,数组越界;loitering问题(没太想明白)
在这里插入图片描述在这里插入图片描述
不为数组大小的设置限制,可以在push元素前分配合适的空间再copy在push新元素。每次push前都要copy之前的元素,导致时间复杂度为N2。虽然使用了Array ,性能还不如linklist呢。主要问题就是resize Array size的操作过于频繁!插入n个元素,意味着resize Array size n次!为了减少resize的次数,我们能否在分配空间的时候多分配一些?!此时,resize的操作仅当array的空间全部满了才进行!而不是每push一次就resize!
同样插入n个元素,我们来比较时间复杂度:第一种方法,resize 操作执行了n次 ,每次复制数组元素都需要访问数组两次,因此可得出时间复杂度为quadratic time!第二次方法,resize操作进行了lgN次,进行copy时同样需要访问数组两次
在这里插入图片描述解释一下(2+4+8+N)中的N,插入n个元素所对应的resize次数为lgN,起初只有一个元素做resize,需要执行的操作次数为2,doubling size后,二个元素时需要执行操作次数为4,4个元素执行操作次数为8 (第三次resize),依次可得每次resize执行操作次数为2i,若插入n个元素,需要resize lgN次!利用等比求和公式可得时间复杂度近似为3N!
在这里插入图片描述
pop元素时,我们希望数组大小也可以做到动态变化!第一种想法:当数组处于半满状态,resize数组!如果客户经常执行push-pop-push操作,将导致不断resize array。
在这里插入图片描述
问题出在没有找到合适resize 数组的状态点!于是,另一种做法指出当数组处于1/4满,则将实际的数组大小减半!

在这里插入图片描述
在这里插入图片描述stack如果有N个元素,如果数组大小==栈中元素个数,此时为数组分配的内存空间为8N;又如果栈元素个数j恰好是1/4 array的大小,因此数组大小为32N。
在这里插入图片描述对于栈的两种实现,我们该如何选取呢?array实现的stack平均时间复杂度低,而且占用的内存空间相对更少,大多数情况下,push和pop很快(快于linklist stack)!但是客户需要时时刻刻很快,array stack就不是适用了!毕竟存在着resize操作,此时应该选择linklist stack,以一定的内存消耗来换取时间性能。
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述在这里插入图片描述queue:
在这里插入图片描述
1、linklist version

在这里插入图片描述在这里插入图片描述
2、array version

generic:
在之前的queue和stack实现中,我们都是针对某一个特殊的数据类型而编写程序,但实际上我们的数据有不同的类型,这里提出了两种solution:使用强制类型转换、generic编程。
强制类型转换:
在Java中所有的类都是Object的子类,编写stackObject类,客户端通过强制类型转化来特殊化stack。强制类型转化发生在客户端,不好!run-time error,不好!
在这里插入图片描述
泛型编程:通过使用类型参数来代替具体的数据类型,当发生mismatch时属于compiler-error!
在这里插入图片描述
在这里插入图片描述对于generic array stack implement来说,Java不支持generic array ,这里先使用Object array 在强制类型转化为typename 。
在这里插入图片描述
在这里插入图片描述iteration机制:
若希望实现的数据结构提供遍历功能,可以使用Java 的iteration机制,可以不使用,但是对于不同的数据类型,客户需要使用调用不同的方法,iteration为客户程序提供简单的遍历机制:for-each statement!
现在来修改我们之前设计的stack类:
1、implement Iterable 接口(实现返回iterator的方法)
2、添加内部类iterator(类内实现hasNext 方法和next方法 ,在hasNext 和 next方法隐蔽了不同的实现 )
在这里插入图片描述在这里插入图片描述在这里插入图片描述application:
1、不同的编程语言库都支持stack 、queue类型,但是如果不了解其性能,不建议使用!
2、栈的应用:
函数的调用(递归)

在这里插入图片描述计算中缀表达式,相较于我之前接触算法来说,思路更为简单!直接使用两个栈:操作数栈、操作符栈,根据操作符间的关系确定何时出栈入栈。括号的优先级高则先计算再将结果放入栈中继续参与运算。
在这里插入图片描述在这里插入图片描述在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值