Data structure Chapter 3 stack and queue

Chapter 3 stack and queue

3.1 stack

3.1.1 basic concept of stack

  1. 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

  1. 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

  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;
}

  1. 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

3.1.3 chain storage structure of stack

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

  1. 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

  2. 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

  1. 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.

  1. 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:

  1. 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

  1. 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

  1. 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 brackets

Bracket pair offset

3.3.2 application of stack in expression evaluation

  1. 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

  1. Infix, suffix expression

    Infix expression: 1+B * (C-D)-E/F
    Suffix expression: ABCD- * +EF/-

  2. 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.

  3. 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)

Tags: data structure

Posted on Sat, 20 Nov 2021 19:55:58 -0500 by mk_silence