《数据结构与算法分析:C语言描述_原书第二版》CH3表、栈和队列_reading notes

表、栈和队列是最简单和最基本的三种数据结构。基本上,每个有意义的程序都将明晰地至少使用一种这样的数据结构,好比栈在程序中老是要间接地用到,无论你在程序中是否作了声明。node

本章学习重点:算法

  • 理解抽象数据类型(ADT)的概念学习如何对表进行有效的操做
  • 熟悉栈ADT及其在实现递归方面的应用
  • 熟悉队列ADT及其在操做系统和算法设计中的应用

ADT数组

抽象数据类型(abstract data type)是一个操做的集合,是数学的抽象,在ADT中不涉及如何实现操做的集合,这能够看做是模块化设计的扩充。对于每种ADT并不存在什么法则来告诉咱们必需要有哪些操做,这是一个设计决策、错误处理和关系重组,通常取决于程序设计者。服务器

表ADT网络

表能够用数组来实现,查找操做以线性时间执行,插入和删除操做的最坏状况为O(N)。因为插入和删除的低效以及表的大小必须事先已知,因此简单数组通常不用来实现表这种数据结构。为了不插入和删除的时间开销,咱们须要容许表能够不连续存储,不然表的部分或所有须要总体移动。程序设计中经常留出一个称之为表头(header)或哑结点(dummy node)的标志结点,它解决了几个棘手的问题:从表头插入元素;删除表头元素;通常删除问题,须要记住被删除元素前面的表元。数据结构

三个用例:模块化

  • 计算一元多项式,对于大部分项都有的稠密多项式能够用数组来实现,反之其运行时间不被接受,这时候能够用链表快速实现之。
  • 实现基数排序。
  • 多重表。多名学生随机选多门课(40000名学生和2500门课)用多表实现比二维数组实现高效得多。

栈ADT函数

栈是限制插入和删除只能在一个位置上进行的表,该位置是表的末端,叫作栈的顶,只有栈顶元素是能够访问的。栈有时也称LIFO(后进先出)表。同表同样,栈既能够用数组,也能够用链表来实现。因为CreateStack在栈的数组实现中须要一个初始化数组长度的参数,而在链表实现中不须要参数,所以后者的实现中不添加哑元的话,那么这个使用栈的例程就须要知道正在使用的是哪一种方法。不幸的是,效率和软件理想主义经常发生冲突。post

三个应用:学习

  • 平衡符号,能够用于编译器检查程序的语法错误。  

       算法描述:作一个空栈,读入字符直到文件尾。若是字符是一个开放符号,则将其推入栈中。若是字符是一个封闭符号,

    则当栈空时报错。不然,将栈元素弹出。若是弹出的符号不是对应的开放符号,则报错。在文件尾,若是栈非空则报错。

    能够看出,算法是线性的且是在线(on-line)的。  

  • 后缀表达式。如操做4.99 * 1.06 + 5.99 + 6.99 * 1.06采用后缀(postfix)或逆波兰(reverse Polish)记法:4.99 1.06 * 5.99 + 6.99 1.06 * +  

      算法描述:当见到一个数时就把它推入栈中,遇到一个运算符时就做用于从该栈弹出的两个数上,将所得结果推入栈中。

    时间花费O(N).除此以外,咱们还能够用栈将一个标准形式(也称中缀式(infix))转换成后缀式。  

  • 函数调用。很少说了,CSAPP比这里详细得多。

队列ADT

像栈同样,队列也是表。然而,使用队列时插入在一端进行而删除则在另外一端进行。队列能够用数组实现也能够用链表实现。 

三个应用:

  • 看成业送交给一台行式打印机,它们就按照到达的顺序被排列起来。所以,被送往行式打印机的做业基本上是放在一个队列中。这个例子是关于计算机网络的。用许多中PC机的网络设置,其中磁盘是放在一台叫作文件服务器的机器上的。使用其余计算机的用户是按照先到先使用的原则访问文件的,所以其数据结构是一个队列。进一步的例子:
  • 当全部的接线员忙的不可开交的时候,对大公司的传呼通常都被放在一个队列中。             
  • 在大规模的大学里,若是全部的终端都被占用,因为资源有限,学生们必须在一个等待表上签字。在终端上呆的时间最长的学生将首先被强制离开,而等待时间最长的学生则将是下一个被容许使用终端的用户。正如栈同样,队列还有其余丰富的用途,这样一种简单的数据结构居然可以如此重要,实在使人惊奇。

Summary

本章描述了一些ADT的概念,而且利用三种最多见的抽象数据类型(ADT)阐述了这个概念。主要目的就是将抽象数据类型的具体实现与它们的功能分开。程序必须知道操做都作些什么,可是若是不知道如何去作实际上更好。  

表、栈和队列或许在所有计算机科学中是三个基本的数据结构,大量的例子证实了它们普遍的用途。特别地。咱们看到栈是如何用来记录过程和函数调用的,已经递归其实是如何实现的。理解这些过程是很是重要的,其缘由不仅是由于它使得过程语言成为可能,并且还由于知道递归的实现从而消除了围绕其使用的大量谜团。虽然递归很是强大,可是它并非彻底随意的操做;递归的误用和乱用可能致使程序崩溃。

相关文章
相关标签/搜索