Chapter 2 Stacks and Queues
Development environment
windows 10
visual studio 2019
c
1 stack
仅一头进出
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 50 //定义栈中元素的最大个数
#define true 1
#define false 0
typedef int ElemType; //定义栈的元素类型
1.0 Brawling
- For nnn different elements are pushed into the stack, and the number of out-stack sequences is1 n + 1 C 2 nn \frac{1}{n+1}C^n_{2n}n+11C2 nn【Cattelland Number】
1.1 Sequential stack
typedef struct {
ElemType data[MAXSIZE]; //存放栈中元素
int top; //栈顶指针
}SqStack;
void InitStack(SqStack S);
_Bool StackEmpty(SqStack S);
_Bool Push(SqStack S, ElemType x);
_Bool Pop(SqStack S, ElemType x);
_Bool GetTop(SqStack S, ElemType x);
_Bool DestroyStack(SqStack* S);
1.1.1 Stack initialization
Initialize an empty stack S.
void InitStack(SqStack S) {
S.top = -1; //初始化栈顶指针
}
If S.top=0 is initialized, the stack operation is S.top++ instead of ++S.top (you know, huh). Contact the assembly knowledge that I have almost forgotten, it is best to +1 first, and then save.
1.1.2 Null operation
Judge whether a stack is empty, return true if stack S is empty, otherwise return false.
_Bool StackEmpty(SqStack S) {
if (S.top == -1)
return true; //栈空
else
return false; //不空
}
1.1.3 Push into the stack
Push the stack, if the stack S is not full, add x to make it the top of the new stack.
_Bool Push(SqStack S, ElemType x) {
if (S.top == MAXSIZE - 1) //栈满,报错
return false;
S.data[++S.top] = x; //指针先+1,再入栈
return true;
}
1.1.4 Pop
Pop the stack, if the stack S is not empty, pop the top element of the stack and return with x.
_Bool Pop(SqStack S, ElemType x) {
if (S.top == -1) //栈空,报错
return false;
x = S.data[S.top--]; //先出栈,指针再-1
return true;
}
1.1.5 Read the top element of the stack
Read the top element of the stack. If the stack S is not empty, return the top element with x.
_Bool GetTop(SqStack S, ElemType x) {
if (S.top == -1) //栈空,报错
return false;
x = S.data[S.top]; //x记录栈顶元素
return true;
}
1.1.6 Destroy the stack
Destroy the stack and release the storage space occupied by S.
_Bool DestroyStack(SqStack* S) {
if (!S)
return false;
free(S);
return true;
}
1.2 Chain stack
typedef struct Linknode {
ElemType data; //数据域
struct Linknode* next; //指针域
}* LiStack; //栈类型定义
Pop and stack are all operated at the head node
1.2.1 Stack
If you push s
s->next = L->next;
L->next = s;
1.2.2 Pop
If the top element s is popped from the stack
s = L->next;
L->next = s->next;
free(s);
2 queue
仅一头进,另一头出
#define MAXSIZE 50 //定义队列中元素的最大个数
#define true 1
#define false 0
typedef int ElemType; //定义队列的元素类型
typedef struct {
ElemType data[MAXSIZE]; //存放队列元素
int front, rear; //队头指针和队尾指针
}SqQueue;
void InitQueue(SqQueue Q); //初始化队列,构造一个空队列Q
_Bool QueueEmpty(SqQueue Q); //判队列空,若队列Q为空返回true,否则返回false
void EnQueue(SqQueue Q,ElemType x); //入队,若队列Q未满,将x加入,使之成为新的队尾
_Bool DeQueue(SqQueue Q, ElemType x); //出队,若队列Q非空,删除队头元素,并用x返回
_Bool GetHead(SqQueue Q, ElemType x); //读队头元素,若队列Q非空,则将队头元素赋值给x
2.1 Queue basic operations
2.1.1 Initialization (queue empty condition)
Q.front == Q.rear == 0;
2.1.2 Incoming
Element s into the team
data[Q.rear++] = s;
2.1.3 Departure
Head element s out of the team
s = data[Q.front++];
2.2 Circular queue
Circle in circle
2.2.0 Other ways to distinguish between empty and full teams
方式1:增设表示元素个数的数据成员size
Q.size == 0; //队空
Q.size == MAXSIZE; //队满
方式2:增设判断队列是否已满的数据成员tag
tag = 0时,因删除导致 Q.rear == Q.front; //队空
tag = 1时,因插入导致 Q.rear == Q.front; //队满
方式3:牺牲一个单元来区分队空和队满,入队时少用一个队列单元
2.2.1 Team empty conditions
Q.front == Q.rear == 0;
2.2.2 Full team conditions
(Q.rear + 1) % MAXSIZE == Q.front;
2.2.3 Queue length
(Q.rear + MAXSIZE - Q.front) % MAXSIZE;
2.2.3 Incoming
data[Q.rear] = s;
Q.rear = (Q.rear + 1) % MAXSIZE;
2.2.4 Departure
s = data[Q.front];
Q.front = (Q.front + 1) % MAXSIZE;
2.2 Chain queue
A singly linked list with a leading node.
void InitQueue(LinkNQueue Q);
_Bool QueueEmpty(LinkNQueue Q);
void EnQueue(LinkNQueue Q,ElemType x);
_Bool DeQueue(LinkNQueue Q, ElemType x);
_Bool GetHead(LinkNQueue Q, ElemType x);
typedef struct {
//链式队列结点
ElemType data;
struct LinkNode* next;
}LinkNode;
typedef struct {
//链式队列
LinkNode* front, * rear; //队列的队头和队尾指针
}LinkNQueue;
2.2.1 Queue initialization
void InitQueue(LinkNQueue Q) {
Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode)); //建立头结点
Q.front->next = NULL; //初始为空
}
2.2.2 Empty the team
_Bool QueueEmpty(LinkNQueue Q) {
if (Q.front == Q.rear)
return true;
return false;
}
2.2.3 Enrolling
void EnQueue(LinkNQueue Q, ElemType x) {
LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
/*创建新结点,插入到链尾*/
s->data = x;
s->next = NULL;
Q.rear->next = s;
Q.rear = s;
}
2.2.4 Departure
_Bool DeQueue(LinkNQueue Q, ElemType x) {
if (QueueEmpty(Q))
return false; //空队
LinkNode* s = Q.front->next; //跳过头结点
x = s->data;
Q.front->next = s->next;
if (Q.rear == s)
Q.rear = Q.front; //若原队列中只有一个结点,删除后边空
free(s);
return true;
}
2.2.5 Read the value of the head element
_Bool GetHead(LinkNQueue Q, ElemType x) {
if (QueueEmpty(Q))
return false; //空队
LinkNode* s = Q.front->next; //跳过头结点
x = s->data;
return true;
}
2.3 Deque
Both sides can enter and leave the team.
2.3.1 Deque with limited output
A double-ended queue is allowed to enter and dequeue at one end, and only enter the queue at the other end.
2.3.2 Deque with limited input
A double-ended queue that allows enqueue and dequeue at one end and only dequeue on the other end.
3 Application of stack and queue
3.1 Application of the stack
(1) Bracket matching
(2) Expression evaluation-postfix expression (reverse Polish notation)
(3) Recursion → non-recursion:
recursion:
recursion itself is applied in the definition of a function, procedure or data structure The model cannot be defined cyclically, and must meet two conditions:
<1> Recursive expression (recursive body)
<2> Boundary conditions (recursive exit)
3.2 Application of queue
(1) Hierarchical traversal [Save the next processing sequence]
(2) Application in computer system
<1> Solve the problem of speed mismatch between the host and external devices
<2> Solve the problem of resource competition caused by multiple users
4 Compressed storage of special matrix
4.1 Array storage structure
Two-dimensional array a[weight][height]
size: element storage unit
4.1.1 First row and then column
L O C ( a i , j ) = L O C ( a 0 , 0 ) + [ r o w × ( h e i g h t + 1 ) + c o l ] × s i z e LOC(a_{i,j})=LOC(a_{0,0})+[row×(height+1)+col]×size LOC(ai,j)=LOC(a0,0)+[row×(height+1)+col]×size
4.1.2 Column first
L O C ( a i , j ) = L O C ( a 0 , 0 ) + [ c o l × ( w e i g h t + 1 ) + r o w ] × s i z e LOC(a_{i,j})=LOC(a_{0,0})+[col×(weight+1)+row]×size LOC(ai,j)=LOC(a0,0)+[col×(weight+1)+row]×size
4.2 Compressed storage of matrix
4.2.1 Symmetric matrix
4.2.2 Triangular matrix
4.2.3 Tridiagonal matrix
4.3 Sparse matrix
5 Reference
Benevolent