数据结构-浙江大学-栈、队列(三)

    技术2023-12-26  73

    栈有很广泛的应用,在函数调用、递归、表达式求值等等都要用到栈。


    一个数组实现两个栈



    这里,老师讲的是单向链表的头作为栈顶。 单向链表的头可以做插入、删除操作,这个很明显。 老师讲的,单向链表的尾部,只能做插入,不能做删除 但是,我们基于前面的线性链表可以知道,删除是整个链表都可以进行的操作,咋就尾部不能做删除操作了呢?

    翻阅了一下手头的资料,发现: 《大话数据结构》 《王道-数据结构》 好像,只是便于操作,才是放在了单链表的头部。 而不是单链表的尾部删除后找不到前面的节点这个原因。



    堆栈的应用:表达式求值


    队列

    什么是队列 队列(Queue):具有一定操作约束的线性表 插入和删除:只能在一端插入,另一端删除; 数据插入称为入队(AddQ) 数据删除称为出队(DeleteQ) 遵循:先进先出的原则:FIFO 如上面的例子,此顺序存储队列(数组)有6个元素。 我们使用front和rear的相对位置,可以计算队列的长度。 front和rear的相对位置有:0(相等),1(1个元素),2,3,4,5

    而,队列有:0(空),1,2,3,4,5,6(满)情况。

    也就是,我们想使用n个关系,去表示n+1种关系,显然是做不到的。 这也就是空和满无法做到区分。

    解决方案:

    使用额外标记Size或者Tag域 使用Size表示元素的个数,这样当front=rear的时候,判断size大小即可 使用Tag,入队tag = 1,出队tag = 0。当front=rear的时候,如果tag = 1,则是满。如果tag = 0,则是空。仅使用n-1个数组空间

    还是上面的图,[5]后面变成[0],如何实现呢? 将 (5 + 1)%6 = 0; 所以,在下面的图片中,判断队列满或者不满,使用的是:

    Front指向的是队列的头元素的前面的一个位置 Rear指向的是队列的尾部元素当前位置 空的时候,fraont = rear = -1

    队列的链表存储

    按照前面老师讲的,尾部不能做删除操作,很容易知道: 链表的头部做Front和Rear都可以; 链表的尾部只能插入,不能删除; 那么,链表的头部是队列的Front,链表的尾部是队列的Rear。

    首先,这个已经写明了,是不带头结点的链式队列 当队列为空的时候,就是PtrQ->front == NULL的时候 当队列只有一个元素的时候,就是头和尾相等的时候。


    多项式加法运算

    中间有小伙伴说,case1中,rear传指针,里面怎么没有rear++ 其实,这个是Attach函数,你怎么知道在函数里面没有做rear++操作呢?

    Polynomial *pRear = &rear 那么,pRear存储的就是:指针变量rear 的地址。 *pRear = rear 因为涉及到修改rear->link的值,如果传入的是rear,那么函数里面的rear->link的修改,跟外面的rear->link没有关系。 所以,为了修改外面的rear->link,所以传入的是&rear。


    一元多项式的加法与乘法运算

    这个前面有代码的具体实现,可以往上翻。

    (a+b+c)*(d+e+f) 方法1: a*(d+e+f) + b*(d+e+f) + c*(d+e+f) 方法2: 初始结果多项式:a*d + a*e +a*f 将b*d + b*e + b*f + c*d + c*e + c*f计算出的每一个乘法都一步一步插入到初始结果后面

    Processed: 0.018, SQL: 9