数据结构复习——栈与队列

(一)栈

1.栈的顺序存储结构

采用数组的形式

2.栈的链式存储结构

入栈和出栈采用头插法(考虑有没有头结点的情况)

3.栈的应用

1.栈实现左右括号匹配

思想:

1.碰到左括号,则将左括号入栈

2.碰到右括号,取出栈顶元素

3.重复步骤1、2,

若出现 以下两种情况,则说明匹配异常。:

一、碰到右括号但栈为空 

二、遍历完所有括号,但栈不为空

2.栈实现后缀表达式求值

思想:只需要1个操作数栈

从左到右扫描表达式

1.若出现操作数,则操作数入栈

2.若出现运算符,则从操作数栈弹出两个操作数进行运算,将运算结果入栈

3.重复步骤1、2,扫描完成后最终操作数栈中保存的即为最终结果

3.栈实现中缀表达式转后缀表达式

思想:

从左到右扫描表达式

1.若为操作数则直接输出到后缀表达式中

2.若为'(' 则'('直接入栈 ;

若为')'则将栈顶元素不断出栈输出到后缀表达式中,直至碰到'('( '(' 也出栈,但不输出到后缀表达式中 );

若为其它运算符,则当栈为空/该运算符的优先级大于栈顶元素优先级时,入栈;否则不断出栈输出到后缀表达式中,直到栈顶运算符的优先级小于该运算符,让该运算符入栈。

总之,保持栈顶元素优先级比较高。

4.栈实现中缀表达式的计算

思想:

合并 中缀转后缀+后缀表达式的计算

从左到右扫描表达式

1.若为操作数,则进入操作数栈

2.若为运算符,则按照中缀转后缀中的运算符规则,弹出/压入运算符,弹出的运算符与操作数栈中的栈底两个数进行运算,将运算结果再压入栈中。

3.重复1、2直到扫描完成表达式

5.栈实现递归函数调用

思想:

函数调用时需要用一个递归工作栈,保存函数的返回地址、实参、局部变量,进入一次递归,则将这些信息入栈,退出函数调用时弹栈即可。

(二)队列

1.队列的顺序存储结构

讨论一般队列和循环队列。

一般的队列,数组下标front表示队列头(当队列为空时,front指向的队列头还没有装入元素),只有当出队时,front进行更新front++;数组下标rear表示队列尾的下一个元素,即入队时,直接让Q[rear] = x;rear++即可,只有当入队时rear才会进行更新,出队时rear不进行更新。

一般的队列采用数组的形式存储,这样的缺点时,如果一直出队,则front下标会一直增大,但front之前的空间保持空闲,造成空间浪费,因此采用循环队列。

循环队列:

入队:Q[rear] = x; rear = (rear+1) % maxsize;

出队:  front = (front + 1) % maxsize;

判断是否为空还是为满: 稍微麻烦些,这是因为当队列为空的开始状态时 front=rear,当队列完全装满时,front=rear。因此不能直接根据front和rear的大小进行判断队列是否为空还是为满。有三种方式可以判断:

1.牺牲一个单元  这样为空可用 front==rear,为满可用 (rear+1)%maxsize==front来判断

2.设置队列的属性size 为空用size==0,为满用size==maxsize判断

3.设置tag, 删除操作设置tag=1,插入操作设置tag=0,队列为空用rear==front&&tag==1,队列为满用rear==front&&tag==0判断

2.队列的链式结构

队列的链式结构是带有头结点的链表,设置队头指针Q.front和队尾指针Q.rear,队头指针指向头结点,队尾指针就指向队尾元素。

入队时 在队尾后添加一个节点即可

出队时 出的是头结点后面的那个节点,出队时rear指针一般不动,除非出队以后队列变成了空指针,此时赋值Q.rear = Q.front

判断为空 即用Q.rear = Q.front进行判断

3.队列的应用

1.队列实现杨辉三角

核心:每个元素出完队列,保存该元素的值,与队头元素相加。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值