Chapter 3 stack and queue
3.1 stack
3.1.1 basic concept of stack- definition
A linear table that can only operate in one segment
Properties: last in, first out
N different elements into the stack
2. Basic operation of stack
InitStack(&S)//Initialize an empty stack S. StackEmpty(S)//Judge whether a stack is empty. If the stack s is empty, return true; otherwise, return false Push(&S,x)//Enter the stack. If the stack s is not full, add x to make it the top of the new stack. Pop(&S,&x)//Out of the stack. If the stack s is not empty, the top element of the stack will pop up and return with x. GetTop(s,&x)//Read the stack item element. If the stack s is not empty, use x to return the top element of the stack. DestroyStack(&S)//Destroy the stack and release the storage space occupied by the stack s ("&" means reference call).3.1.2 sequential storage structure of stack
- Implementation of sequential stack
The stack with sequential storage is called sequential stack. A group of storage units with continuous addresses are used to store the data elements from the bottom of the stack to the top of the stack, and a pointer (top) is attached to indicate the position of the current top of the stack
Sequential storage type of stack
#define MaxSize 50 typedef struct{ ElemType data[MaxSize]; int top; }SqStack;
Stack top pointer: s.top, initially set s.top=-1; Stack top element: s.data[S. top]
Stack entry: when the stack is not satisfied, the stack top pointer first adds 1, and then sends the value to the stack top element.
Stack out operation: when the stack is not empty, first take the element value of the stack item, and then reduce the stack top pointer by 1
Stack empty condition: s.top==-1; Stack full condition: S.top==MaxSize-1; Stack length: s.top+1
- Basic operation of sequential stack
(1) Initialization
void InitStack(SqStack &s){ s.top=-1;//Initialization pointer 5 }
(2) Stack empty
bool StackEmpty(SqStack S){ if(S.top==-1) //stack empty return true; else return false; }
(3) Enter the stack
bool Push(SqStack &S,ElemType x){ if(S.top == MaxSize-1) //full stack, return error return false; S.data[++S.top] = x; //The pointer is incremented by 1 before entering the stack return true; }
(4) Out of stack
bool Pop(SqStack &S,ElemType &x){ if(S.top==-1) //empty stack ,error return false; x=S.data[top--]; //First out of the stack, and then minus 1 return true; }
(5) Read stack top element
bool GetTop(SqStack S,ElemType &x){ if(S.top ==-1) return false; x = S.data[S.top]; return true; }
- Shared stack
The stack top pointer of both stations points to the stack top element. When top0=-1, stack 0 is empty, and when top1=MaxSize, stack 1 is empty; It is judged that the stack is full only when two station pointers are adjacent (top1-top0=1)
When stack 0 enters the stack, top0 first adds 1 and then assigns value; when stack 1 enters the stack, it first subtracts 1 and then assigns value; When it comes out of the stack, it's just the opposite
The advantage of chain stack is that it is convenient for multiple stacks to share storage space and improve efficiency
Single linked list is usually used, and all operations are specified in the header of the single linked list
typedef struct Linknode{ ElemType data; struct Linknode *next; }*LiStack;
3.2 queue
3.2.1 basic concept of queue-
Queue definition
It is only allowed to insert at one end of the table and delete at the other segment of the table
The first to queue up is also the first to leave the queue. Characteristics: first in, first out
-
Common basic operations of queue
InitQueue (&Q)//Initialize the queue and construct - an empty queue Q. QueueEmpty (Q)//Judge that the queue is empty. If queue Q is empty, return true; otherwise, return false EnQueue(&Q,x)//Join the queue. If queue Q is not full, add x to make it a new tail DeQueue (&Q, &x)//Out of the queue. If queue e is not empty, delete the queue header element and return it with x GetHead(Q, &x)//Read the queue header element. If queue Q is not empty, assign the queue header element to X.3.2.2 sequential storage structure of queue
- Sequential storage of queues
Sequential implementation: allocate a continuous storage unit to store the elements in the queue, and attach two pointers: the queue head pointer front points to the queue head element, and the queue tail pointer rear points to the next position of the queue tail element
#define MaxSize 50 typedef struct{ ElemType data[MaxSize]; int front, rear; //Queue head pointer and queue tail pointer }SqQueue;
Initial state (team empty condition): Q. front==Q. rear==0
Queue entry operation: when the queue is not satisfied, first send the value to the queue end element, and then add 1 to the queue end pointer.
Out of queue operation: when the queue is not empty, first take the value of the queue head element, and then add 1 to the queue head pointer.
- Circular queue
When the head of the queue pointer Q.front = MaxSize-1, it will automatically reach 0 when it advances another position, which can be achieved by division and remainder (%)
Initial: Q. front=Q. rear=0
Team leader pointer 1q. Front = (Q. front + 1)% maxsize
End of queue pointer 1:Q. rear= (Q. rear+1) 8MaxSize
Queue length: (Q. rear+MaxSize-Q. front) 8MaxSize
Air condition: Q.front == Q.rear
How to judge the full queue: (Q.rear+1)%MaxSize == Q.front
In order to distinguish between empty and full teams, there are three methods:
- Operation of circular queue
(1) Initialization
void InitQueue(SqQueue &Q){ Q.rear=Q.front=0; //Initializing the queue head and tail pointers }
(2) Judge the team empty
bool isEmpty(SqQueue Q){ if(Q.rear ==Q.front) return true; //Team air condition else return false; }
(3) Join the team
bool EnQueue(SqQueue &Q,EeleType x){ if((Q.rear+1)%MaxSize==Q.front) return false; //When the team is full, an error is reported Q.data[Q.rear] = x; Q.rear=(Q.rea+1)%MaxSize;//End of line pointer plus 1 to take mold return true; }
(4) Out of the team
bool DeQueue(SqQueue &Q,ElemType &x){ if(Q.rear == Q.front) return false; //Team empty error reporting x=Q.data[Q.front]; Q.front = (Q.front+1)%MaxSize; //Team head pointer plus 1 to take mold return true; }3.2.3 chain storage structure of queue
- Chained storage of queues
typedef struct{ ElemType data; struct LinkNode *next; }LinkNode; typedef struct{ //Chain queue LinkNode *front,*rear; //Pointer to the header and tail of the queue }LinkQueue;
When Q.front== NULL and Q.rear==NULL, the chain queue is empty
Chain queue of leading node
- Basic operation of chain queue
(1) Initialization
void InitQueue(LinkQueue &Q){ Q.front=Q.rear =(LnikNode*)malloc(sizeof(LinkNode)); //Create header node Q.front->next=NULL; //Initial null }
(2) Judge the team empty
bool IsEmpty(LinkQueue Q){ if(Q.front==Q.rear) return true; else return false; }
(3) Join the team
void EnQueue(LinkQueue &Q,ElemType x){ LinkNode *s=(LinkNode *)malloc(sizeof(LinkNode)); s->data=x;s->next=NULL; //Create a new node and insert it at the end of the chain Q.rear->next=s; Q.rear=s; }
(4) Out of the team
bool DeQueue(LinkQueue &Q,ElemType &x){ if(Q.front==Q.rear) return false; //Air force LinkNode *p=Q.front->next; x=p->data; Q.front->next=p->next; if(Q.rear==p) Q.rear=Q.front; //If the original queue has only one node, it will become empty after deletion free(p); return true; }3.2.4 queue at both ends The queue at both ends that allows insertion and deletion at one end but allows only insertion at the other end is called the queue at both ends with limited output
3.3 application of stack and queue
3.3.1 application of stack in bracketsBracket pair offset
3.3.2 application of stack in expression evaluation- Pithy formula
The suffix is the symbol stack
Infix is a stack of letters
The top element of the stack is higher (or equal) than the one to be entered
-
Infix, suffix expression
Infix expression: 1+B * (C-D)-E/F
Suffix expression: ABCD- * +EF/- -
The process of calculating the expression value through suffix is as follows:
Scan each item of the expression in sequence, and then do the following corresponding operations according to its type: if the item is an operand, push it into the stack: if the item is an operator < OP >,
Then two operands Y and X are continuously exited from the stack to form the operation instruction x < OP > Y, and the calculation result is pushed back into the stack. When all items of the expression are scanned and processed, the final calculation result is stored at the top of the stack.
-
Infix to suffix method
Scan infix expressions from left to right. When numbers are encountered, add suffix expressions
Operator encountered:
If yes (stack)
If yes), the operator in the war is added to the suffix expression at one time until (, which is deleted from the stack(
For operators other than parentheses, when their priority is higher than the top of the stack operator other than (), they will be directly put on the stack. Otherwise, from the top of the stack, operators with higher priority and equal priority than the currently processed operators will pop up successively until an operator with lower priority or an open parenthesis is encountered
(1) a+b - a * ( (c+d) /e-f) +g
First, we need to change the stack according to the priority of the operator < OP >. We use icp to represent the priority of the currently scanned operator ch. the priority of the operator after entering the station is isp, so the priority of the operator is shown in the following table, indicating that [isp] is the priority number in the stack and icp is the priority number out of the stack
(2)