数据结构 栈和队列总结

第三章    栈和队列

一、栈

1. 栈空条件:S.top == -1;栈满:S.top == MaxSize – 1; 栈长:S.top + 1;

以上当然是顺序栈的情况。

  1. 或许之前存储的元素仍然在栈中,但top指针已经指向了新的栈顶,也就起到了删除的作用。
  2. 进栈操作:指针先加1,再入栈。    S.data[++S.top] = x;
  3. 出栈操作:先出栈,指针再减1。    x=S.data[S.top--];

注:上述是栈顶指针指向的就是栈顶元素的情况,若指针初始化为S.top=0,则入栈操作变为S.data[S.top++] = x; 出栈操作变为x=S.data[--S.top]。

  1. 共享栈,仅当两个栈顶指针相邻(top1 – top0 = 1)时,栈满。
  2. 当不带头结点时,链栈的头指针指向栈顶元素
  3. 出栈序列的个数,卡特兰数h(n)=C(2n,n)/(n+1)。

课后题易错:

  1. 采用非递归方式重写递归程序时必须使用栈。   

错误,反例:计算斐波拉契数列迭代实现只需要一个循环即可实现。

  1. 函数调用时,系统要用栈保存必要的信息。

 

二、队列

1. 队头(Front)允许删除的一端,队尾(Rear)允许插入的一端。

2. 队列的顺序存储存在“假溢出”问题。无法用Q.rear == MaxSize判断队列是否为满。

3. 循环队列:

      实现方法:

1.设置标识符(此时队空Q.size==0,Q.size == maxSize) 2.牺牲一个单元

Q.front = Q.rear = 0;初始:

入队:Q.rear = (Q.rear + 1) % maxSize;

出队:Q.front = (Q.front + 1) % maxSize;

队满:(Q.rear + 1)%maxSize = Q.front;

队空:Q.front = Q.rear;

队列中元素个数:(Q.rear – Q.front + maxSize)% maxSize;

4. 链队:头指针指向队头结点,尾指针指向队尾结点(单链表中最后一个结点),注意:顺序存储时,尾指针指向队尾元素的下一个位置。

队空:Q.front == Q.rear

5. 双端队列:

      输出受限:允许在一端进入插入和删除,另一端只能插入的双端队列。

      输入受限:允许在一端进行插入和删除,另一端只能删除的双端队列。

 

三、栈和队列的应用

1. 后续表达式中已考虑了运算符的优先级,没有括号。

2. 通过后缀表达式求值:如果是操作数,入栈;如果是运算符,从栈中退出两个操作符Y和X,形成运算指令XY,再将运算结果入栈。

3. 中缀转后缀的手算方法:将两个直接操作数用括号扩起来,再将操作符提出到括号后,最后再去掉括号。例:((a*(b+c))-d)就写成了abc+*d-;

4. 将递归算法转换为非递归算法,通常需要借助栈来实现这种转换。

5. 队列在计算机系统中的应用,第一个方面是解决主机与外部设备之间速度不匹配的问题,第二个方面是解决由多用户引起的资源竞争问题。

 

课后题易错:

  1. 当执行函数时,其局部变量的存储一般采用(栈结构)进行存储。

 

四、数组、矩阵、广义表

1. 数组是n(n>=1)个相同类型数据元素构成的有限序列,每个数据元素称为一个数组元素。

2. 数组是线性表的推广。一维数组可以看做是一个线性表;二维数组可以看做是元素是线性表线性表

3.(矩阵)压缩存储:指为多个值相同的元素只分配一个存储空间,对零元素不分配存储空间。其目的是为了节省存储空间。

4. 对稀疏矩阵进行压缩存储,常用的两种方法是(三元组十字链表)。

5. 三元组(行标,列标,值),稀疏矩阵压缩存储后便失去了随机存取特性。

6. 广义表

广义表的长度:为表中最上层元素的个数。

广义表的深度:为表中括号的最大层数。

表头和表尾:当广义表非空时,第一个元素为广义表的表头,其余元素组成的是广义表的表尾。

头尾链表存储结构:原子结点有2个域:标记域和数据域、广义表结点有3个域:标记域、头指针域与尾指针域(其中标记域用于区分当前结点是原子(用0表示)还是广义表(用1表示),头指针域指向原子或者广义表结点,尾指针域为空或者指向本层的下一个广义表结点)。

你可能感兴趣的:(数据结构)