Data structures (stacks and queues)

Relationship between stack and queue and linear table

Stack and queue are two important linear structures. Stack and queue are also linear tables. Their particularity is that the basic operations of stack and queue are subsets of linear table operations. They are linear tables with limited operations.

Stack

Definition of abstract data type stack

A stack is a linear table that is restricted to insert or delete operations only at the end of the table. Therefore, for the stack, the end of the table has a special meaning, which is called the top of the stack, and the header segment is called the bottom of the stack. An empty table without elements is called an empty stack.
Suppose stack S=( a 1 a_1 a1​ , a 2 a_2 a2​ , a 3 a_3 a3​ ... a n a_n an), then a 1 a_1 a1 is the element at the bottom of the stack, a n a_n an is the top element of the stack. Stack elements by a 1 a_1 a1​ , a 2 a_2 a2​ , a 3 a_3 a3​ ... a n a_n Enter the stack in the order of an , and the first element to exit the stack should be the top element of the stack.
In other words, the stack is modified according to the principle of last in first out. Therefore, stack is also called last in first out linear table

Basic operation of stack

In addition to inserting or deleting at the top of the stack, the basic operations of the stack include stack initialization, empty judgment and fetching top elements.

Definition of stack
#define STACK_INIT_SIZE 100 / / initial allocation of storage space
#Define stockincrement 10 / / storage space allocation increment
typedef struct
{
	(The type of element in the stack)*base;//The value of base is NULL before stack construction and after stack destruction
	(The type of element in the stack)*top;//The stack top pointer points to the next address of the stack top element
	int stacksize;//The currently allocated storage space, in elements
}SqStack;
Construct an empty stack
InitStack(&S)
{
	Operation result: construct an empty stack S
}
int InitStack(SqStack &S)
{
	S.base=(The type of element in the stack*)malloc(STACK_INIT_SIZE*sizeof(The type of element in the stack));
	S.top=S.base;
	S.stacksize=STACK_INIT_SIZE;
	return OK;
}

Destroy stack
DestroyStack(&S)
{
	Initial condition: stack S Already exists
	Operation result: stack S Destroyed
}

Empty stack
ClearStack(&S)
{
	Initial condition: stack S Already exists
	Operation result: Set S Clear to empty stack
}

Determine whether the stack is empty
StackEmpty(S)
{
	Initial condition: stack S Already exists
	Operation result: if stack S If the stack is empty, return TRUE,Otherwise return FALSE
}

Judgment stack S Length of
StackLength(S)
{
	Initial condition: stack s Already exists
	Operation result: Return S The number of elements, that is, the length of the stack
}

Determine stack top element
GetTop(S,&e)
{
	Initial condition: stack S Already exists
	Operation result: use e return S Stack top element
}
int GetTop(SqStack S,(The type of element in the stack)&e)
{
	//If the stack is not empty, use e to return the top element of S and return OK; otherwise, return ERROR
	if(S.top==S.base) return ERROR;
	e=*(S.top-1);
	return OK;
}

Insert a new element to the top of the stack
Push(&S,e)
{
	Initial condition: stack S Already exists
	Operation result: insert element e For the new stack top element
}
int Push(SqStack &S,(The type of element in the stack)e)
{
	//Insert element e as the new stack top element
	if(S.top-S.base>=S.stacksize)//If the stack is full, additional storage space is added
	{
		S.base=(The type of element in the stack*)realloc(S.base,(S.stacksize+STACKINCREMENT)*sizeof(The type of element in the stack));
		S.top=S.base+S.stacksize;//Update the top address of the expanded stack
		S.stacksize+=STACKINCREMENT;
	}
	*S.top++=e;//Assign the new element to the top of the stack. And the top pointer moves back one bit
	return OK;
}

Pop up stack top element
Pop(&S,&e)
{
	Initial condition: stack S Exists and is not empty
	Operation result: delete S The top element of the stack, and e Returns its value
}
int Pop(SqStack &S,The type of element in the stack&e)
{
	//If the stack is not empty, delete the top element of S, return its value with e, and return OK; otherwise, return ERROR
	if(S.top==S.base) return ERROR;
	e=*--S.top;//Point top to the top element of the stack and assign it to e
	return OK;
}

We call the operation of inserting elements into the stack and the operation of deleting elements at the top of the stack out of the stack

The remaining operations that are not specified are similar to ordinary linear tables. You can see the article on linear tables I wrote.
Linear table

Representation and implementation of stack

Like linear tables, stacks have two storage representations. Sequential storage and chain storage

Sequential storage

That is, the sequential storage structure of the stack uses a group of storage units with continuous addresses to store the data elements from the bottom of the stack to the top of the stack, and the pointer top is attached to indicate the position of the top of the stack elements in the sequential stack. The usual practice is to t o p = 0 top=0 top=0 indicates an empty stack. However, it is difficult to estimate the size of the maximum space required during the use of the stack. Therefore, generally speaking, the maximum capacity of the stack should not be limited when initializing the empty stack. A more reasonable approach is to allocate a basic capacity for the stack first, and then expand it paragraph by paragraph when the space of the stack is not enough. You can see how to expand it in the above code
The chain representation of stack is the same as that of ordinary linear table. You can also see my article on linear table

Application examples of stack

Stack and recursive implementation

Tags: data structure queue stack

Posted on Wed, 29 Sep 2021 16:34:07 -0400 by Zay