3.栈和队列2.pptVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
第 * 页 栈的实现方式:与线性表实现方式相似 顺序栈(Array-based Stack) 使用数组实现,本质上是顺序表的简化版(只需栈的大小) 关键是确定哪一端作为栈顶。 链式栈(Linked Stack) 用单链表方式存储,其中指针的方向是从栈顶向下链接。 栈的特点:后进先出 体现了元素之间的透明性 时间效率 所有操作都只需常数时间 O(1) 顺序栈和链式栈在时间效率上难分伯仲 空间效率 顺序栈须说明一个固定的长度 链式栈的长度可变,但增加结构性开销 实际应用中,顺序栈比链式栈用得更广泛 顺序栈容易根据栈顶位置,进行相对位移,快速定位并读取栈的内部元素 顺序栈读取内部元素的时间为 O(1),而链式栈则需要沿着指针链游走,显然慢些,读取第 k 个元素需要时间为 O(k) 一般来说,栈不允许“读取内部元素”,只能在栈顶操作 两个独立的栈 底部相连: 双栈 迎面增长: 对顶栈 对顶栈 top1 top2 函数调用过程 在非递归情况下(不支持递归的程序设计语言中),数据区的分配可以在程序运行前进行,直到整个程序运行结束才释放,这种分配称为静态分配。 采用静态分配时,函数的调用和返回处理比较简单,不需要每次分配和释放被调函数的数据区。 函数的递归调用过程 在递归调用的情况下,被调函数的局部变量不能静态地分配某些固定单元,而必须每调用一次就分配一份新的局部变量,以存放当前函数所使用的数据,当函数结束返回时随即释放。 故其存储分配只能在调用时(程序运行过程中)才能进行,即所谓的动态分配。 在内存中要开辟一个称为运行栈(runtime stack)的足够大的动态区,以处理运行数据。 函数运行时的动态分配过程 用于动态数据分配的存储区可按多种方式组织。典型的组织是将这个存储器分为栈(stack)区域和堆(heap)区域: 栈区域用于分配发生在后进先出LIFO风格中的数据(诸如函数的调用)。 堆区域则用于不符合LIFO(诸如指针的分配)的动态分配。 堆 自由空间 代码区域 全程/静态区域 栈 函数活动记录(activation record) 是动态存储分配中一个重要的部分。 当调用或激活函数时,函数的活动记录包含了为其局部数据分配的存储空间。 临时数据域 局部数据域 机器状态域 控制链 参数域 返回值域 函数的活动记录 运行栈的动态变化 每次调用时,执行进栈操作,将被调函数的活动信息压入栈中,即每当进行一次新的函数调用时,都要在栈的顶部为新的活动记录分配空间。 在每次从函数返回时,执行出栈操作,释放本次的活动记录,恢复到上次调用所分配的数据区中。 被调函数中变量地址全部采用相对于栈顶的相对地址来表示。 一个函数在运行栈上可以有若干不同的活动记录,每个活动记录都代表了一次不同的调用 对于递归函数来说,递归的深度就决定了其在运行栈中活动记录的数目。 当函数递归调用时,函数体的同一个局部变量,在不同的递归层次要分配不同的存储空间,放在内部栈的不同位置。 函数调用时的三个步骤 1.调用函数发送调用信息。调用信息包括调用方要传送给被调方的信息,诸如实参、返回地址等。 2.为被调函数分配需要的局部数据区,用来存放被调方定义的局部变量、形参变量(存放实参)、返回地址等,并接受调用方传送来的调用信息。 3.调用方暂停,把计算控制转到被调方,即自动转移到被调用的函数的程入口。 当被调方结束运行,返回到调用方时,其返回处理也分解为三步进行 1.传送返回信息,包括被调方要传回给调用方的信息,诸如计算结果等。 2.释放分配给被调方的数据区。 3.按返回地址把控制转回调用方。 以阶乘为例: #include stdio.h main( ) { int x; scanf(”%d”, x); printf(”%d\n”, factorial(4)); } long factorial( long n ) { if ( n == 0 ) return 1; else return n * factorial( n-1); // 递归调用 } 递归函数调用过程 3.3 栈与递归 n: 4 控制链 返回地址 第1次调用factorial时的活动记录 x: 4 主程序main的活动记录 栈生长方向 n: 4 控制链 返回地址 第1次调用factorial时的活动记录 x: 4 主程序main的活动记录 n: 3 控制链 返回地址 第2次调用factorial时的活动记录 栈生长方向 3.3 栈与递归 n: 4 控制链 返回地址

文档评论(0)

sis_lxf + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档