1.顺序栈是只运行在一端操作的线性表。n个元素进栈,出栈元素不同排列个数为2n!/n!/n!/(n+1)

普通栈:
#define Maxsize 10
typedef struct{
     ElemType data[Maxsize];
     int top;......栈顶指针,因为栈本质上是数组,所以指针可以简化为一个数
}Sqstack;

共享栈:
typedef struct{
     ElemType data[Maxsize];
     int top0;
     int top1;
}Shstack;

void InitStack(Shstack &S){
     S.top0=-1;
     S.top1=Maxsize;
}
栈满条件:top0+1=top1

链栈就是有头节点的单链表,它所有的操作都是在表头进行,即插入和删除都是头插法和头删法

2.队列是在一端进,一端出的线性表

#define Maxsize 10
typedef struct{
     ElemType data[Maxsize];
     int front,rear;
}SqQueue;

3.队列的插入与删除
因为队列涉及到来头尾的问题,所以为了运算方便,我们使用模运算将队列在逻辑上变为环形

bool EnQueue(SqQueue &Q,Elemtype x){
       if((Q.rear+1)%MaxSize==Q.front)
                 return false;
       Q.data[Q.rear]=x;
       Q.rear=(Q.rear+1)%Maxsize;
       return true;
}

bool DeQueue(SqQueue &Q,Elemtype &x){
       if(Q.rear+1==Q.front)
                 return false;
       Q.data[Q.front]=x;
       Q.front=(Q.front+1)%Maxsize;
       return true;
}

链队就是有头节点的单链表,它入队在队尾进行,出队在队首进行(因为有头节点,所以出队的节点是头节点的后一个节点)

4.判断队列空满的方式
方案一:

牺牲了一个存储空间(即rear指向的那个位置)

方案二:

方案三:

5.其他出题方式

有时rear指向的是队尾元素的下一个位置,即下一个元素应该放的位置(起始时rear=front=0)(前面所写代码和判断方式均建立在这种方式上),有时指向的是队尾元素的位置(起始时rear=n-1,front=0)

前一种:
Q.data[Q.rear]=x;
Q.rear=(Q.rear+1)%Maxsize;

后一种:
Q.rear=(Q.rear+1)%Maxsize;
Q.data[Q.rear]=x;

但是对于后一种,我们不能通过(Q.rear+1)%MaxSize==Q.front判断队满,因为它的队空是这样判断的,因此我们可以牺牲一个存储单元,即当rear=n-2,front=0时就队满,或者通过设置size来判断

5.链式队列

typedef struct LinkNode{
     ElemType data;
     struct LinkNode *next;
}LinkNode;

typedef struct {
     LinkNode *front,*rear;
}LinkQueue;

//带头节点
void InitQueue(LinkQueue &Q){
     Q.front=Q.rear=(LinkNode*)malloc(sizeof(LinkNode));
     Q.front-next=null;
}

//不带头节点
void InitQueue(LinkQueue &Q){
     Q.front=Q.rear=null;
}

6.双端队列是在两端都可以插入删除的队列(在栈中输出合法的队列在双端队列中必定合法)

7.表达式的转换(栈的应用)

波兰表达式=前缀表达式 逆波兰表达式=后缀表达式

(1)中缀表达式转后缀(手算)

(2)后缀表达式的运算(手算)

(3)后缀表达式的运算(机算)

(4)中缀表达式转前缀(手算)

(5)前缀表达式的运算(手算)
从右往左,遇到计算符号就将计算符号后的两个元素与计算符号进行操作

(6)前缀表达式的运算(机算)

(7)中缀表达式转后缀(机算)
注意:如果弹出符号时遇到(就停止,只有遇到)才会弹出)

(8)中缀的计算(机算)
相当于操作符的弹出与中缀转后缀的相同

8.递归中的使用(栈的应用)(栈可以代替递归,但不是唯一方式,斐波拉契可以用循环代替)

9.栈在括号匹配的应用

10.树的层次遍历,图的广度优先遍历以及操作系统的FCFS(队列的应用)

11.总结
栈的应用:递归,递归的消除(也可以用循环,如斐波拉契),进制转换,迷宫求解,括号匹配,表达式转换,执行函数时的局部变量的存储

队列的应用:树的层次遍历,图的广度优先遍历,缓冲区,页面替换算法(FIFO)

12.矩阵的压缩

普通矩阵的压缩:二维数组(矩阵行列从1开始,数组从0开始)

特殊矩阵的压缩:

(1)对称矩阵:只存储主对角线和下三角的数(一维数组)

(2)稀疏矩阵:非0元素远远少于矩阵元素个数

(3)三角矩阵:上三角全为常量(下三角矩阵):按行或者列规则优先存储非常量元素,最后一个元素存储常量元素

(4)三对角矩阵(带状矩阵):按行或者列规则优先存储带状部分元素


悠悠我心
7 声望1 粉丝

« 上一篇
线性表
下一篇 »
树与二叉树

引用和评论

0 条评论