9-Data structure-stack (C language version)

Data Structure - Stack (C language version)

Table of contents

Data Structure - Stack (C language version)

1.Basic knowledge of stack

1. Arrangements and combinations of pushing and popping into the stack

        Scenario 2: Catalan function (calculating the total number of different pops)

2. Basic operations of the stack

        1.Sequential storage

        (1) Sequential stack - definition:

        (2) Sequential stack - empty stack

        (3) Sequential stack-push

        (4) Sequential stack - popping and taking values

        (5)Shared stack

        2. Chain storage

        (1) Chain stack-definition:

        (2) Chain stack - push into the stack

        (3) Chain stack - pop out

        (4) Chain stack-print stack

The total code is as follows: (runnable)



1.Basic knowledge of stack

 Introduction:

        The stack is last-in-first-out, which is logically equivalent to a bucket and can only be operated from the top.

1. Arrangements and combinations of pushing and popping into the stack

        Scenario 1: Given the push sequence, find the possibility of the pop sequence.

        Method: First look at the leftmost side of the stack sequence, then sort by one, take the number popped out of the stack, take the stacked sequence to find the possibility in front of it, and then return to the selection to compare.

        For example: a, b, c, d, e, f are pushed into the stack in sequence , which one may be the one to get out of the stack: generally it is a multiple-choice question, start from the leftmost of the stacking sequence in the options, such as fedcba, if f is out of the stack first , then the order after f must be...e..d..c..b..a. If it matches, look at the second fe. After e is popped off the stack, the next one popped off the stack may be d..c. ..b..a..f is consistent, and then look at the third fed. After d is popped out of the stack, the following may be popped out: c..b..a.., consistent, until the end. So this pop-up is right. Another example: in the popping sequence cabdef, c is popped first, c is popped first, and then maybe ..b..a. The resulting options are popped from the stack as ..a..b. The order is reversed, so this is not,

        Scenario 2: Catalan function (calculating the total number of different pops)

        If n elements are pushed onto the stack in sequence, how many different pop sequences can be obtained?

        Catalan function formula: \frac{C_{2n}^{n}\textrm{}}{n+1}, don’t ask why, just ask, just remember it. Substitute and you will get the result,

2. Basic operations of the stack

 Introduction: According to different storage methods, it is divided into sequential storage and chain storage.

        1.Sequential storage

        Introduction: Sequential storage means defining a structure, which contains an array to store data, and a variable top that records the top of the stack.

As shown in the picture:

        (1) Sequential stack - definition:

#define MaxSize 50  //最大容量
typedef struct
{
	int data[MaxSize];//存储栈数据的一维数组
	int top;	//表示栈顶的变量top
}SqStack;

        (2) Sequential stack - empty stack

        Introduction: You need to see clearly where top points when the stack is empty. The operations of pushing and popping the stack are different for different points. However, you can understand it by drawing a picture.

       Initialization : InitStack(&s) means the stack is empty

//初始化
//因为想要改变结构体内的值,实参形参都变化,所以传栈s的地址进来,栈*S指针接收
void InitStack(SqStack *s)  
{
	s->top=-1;
} 

It is necessary to see clearly what the conditions are when the top stack is empty, and then initialize accordingly.

After initialization, it is to verify whether the stack is empty StackEmpty(s)

//判断是否栈空
void StackEmpty(SqStack s)
{
	if(s.top== -1)
	return 1;
}

        (1)s.top==-1, indicating that the stack is empty

        

        At this time, if I want to assign a value to my array, I definitely need to add 1 to top first, locate the first element of the array, and then assign a value. Therefore, when top==-1 means empty, top is ++ first, and then assigned, and top always points to the top position of the stack.

         (2)s.top==0, indicating that the stack is empty

         At this time, if I want to assign a value to my array, top already points to the first position of the array. I can assign a value directly, and then top++. Therefore, when top==0 means empty, assign value first, then top++, top always points to the next position at the top of the stack.

        (3) Sequential stack-push

        Pushing onto the stack means entering the bucket from the outside. At this time, the overflow situation must be considered to avoid insufficient array capacity. Overflow can be optimized through certain strategies to reduce overflow situations.

               The code is as follows: SqPush(&s,x);

//入栈
void SqPush(SqStack *s,int x)
{
	if(s->top == MaxSize-1)
	{
		exit(-1);//栈满,退出 
	}
	s->top++;
	s->data[s->top]=x;	
} 

        (4) Sequential stack - popping and taking values

        Pop from the stack is taken from the top, and only one end can be operated. Consider underflow when popping the stack. When underflow occurs, the logic is wrong and does not depend on the optimization of the strategy.

code show as below:

//出栈
void Sqpush(SqStack *s,int *n)
{
	if(s->top==-1)
		exit(-1); 
		
	*n=s->data[s->top];
	s->top--;
} 

        (5)Shared stack

        Introduction: When the array space requested by the sequence stack at one time is too large, it will cause a waste of space, and in the end there will be a lot of unused space. Therefore, for two stacks of the same type, we can allow them to access the same stack. Push into the stack from the left and right ends respectively, with the middle being the bottom of the stack.

        Benefits of shared stack : save storage space and reduce the possibility of overflow

 栈空:top0==-1,top1==MaxSize

 The stack is full: they met, top0+1=top1

The shared stack understands the idea.

        2. Chain storage

         Introduction: The stack implemented in the form of a singly linked list is a linked storage of the stack. However, the singly linked list here can only be inserted and deleted from the header.

        The advantages of using chain stacks: it facilitates multiple stacks to share storage space, improves efficiency, does not cause overflow, and makes insertion and deletion more convenient.

       Special convention : A stack implemented using a singly linked list has no head node by default, and the head pointer points directly to the first actual node, and all operations are performed at the head of the table.

        (1) Chain stack-definition:

//栈的链式存储
typedef struct StackNode
{
	int data;
	struct StackNode *next;	
	
}StackNode; 

        (2) Chain stack - push into the stack

Idea: Insert a node, insert the node first, and use the pointer of the P node to store the address of the original first node, which is the address stored in the head node. Then update the head pointer and assign the p node address to the head pointer phead.

 code show as below:

//入栈
StackNode*  StackNodepush(StackNode *phead,int x)
{
	StackNode* p=(StackNode*)malloc(sizeof(StackNode));
	p->data=x;
	p->next=NULL;
	
	if(phead==NULL)
	{
		phead=p;
		
	}
	else
	{
		p->next=phead;
		phead=p; 
	}

	
	return phead;
}

        (3) Chain stack - pop out

        Pop out, that is, use a variable to receive the value popped out of the stack, and then define a temporary pointer to point to the node that needs to be released, and then move the head pointer, update the head pointer to the second node address, and finally Just release the node from the stack.

code show as below:

//出栈
StackNode* StackNodepop(StackNode* phead,int x)
{	//单链表可能为空,所以需要先判断非法情况 
	if(phead==NULL)
	return NULL;
	//取第一结点的值 
	x=phead->data;
	//另外赋值第一个结点 ,为了后面找到它并释放 
	StackNode *p=phead;
	//直接更新头节点 
	phead=p->next;
	free(p);
	return phead;
} 

        (4) Chain stack-print stack

void StackPrint(StackNode* phead)
{
	StackNode* pos =phead;
	while(pos!=NULL)
	{
		printf("%d->",pos->data);
		pos = pos->next;
	}
	printf("NULL\n");
 } 

The total code is as follows: (runnable)

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//顺序栈
#define MaxSize 50
typedef struct
{
	int data[MaxSize];
	int top;	
}SqStack;
//初始化
void InitStack(SqStack *s)
{
	s->top=-1;
} 
//判断是否栈空
int StackEmpty(SqStack s)
{
	if(s.top== -1)
	return 1;
}
//入栈
void SqPush(SqStack *s,int x)
{
	if(s->top == MaxSize-1)
	{
		exit(-1);//栈满,退出 
	}
	s->top++;
	s->data[s->top]=x;	
} 
//出栈
void Sqpush(SqStack *s,int *n)
{
	if(s->top==-1)
		exit(-1); 
		
	*n=s->data[s->top];
	s->top--;
} 
//栈的链式存储
typedef struct StackNode
{
	int data;
	struct StackNode *next;	
	
}StackNode; 
//入栈
StackNode*  StackNodepush(StackNode *phead,int x)
{
	StackNode* p=(StackNode*)malloc(sizeof(StackNode));
	p->data=x;
	p->next=NULL;
	
	if(phead==NULL)
	{
		phead=p;
		
	}
	else
	{
		p->next=phead;
		phead=p; 
	}

	
	return phead;
}
//出栈
StackNode* StackNodepop(StackNode* phead,int x)
{	//单链表可能为空,所以需要先判断非法情况 
	if(phead==NULL)
	return NULL;
	//取第一结点的值 
	x=phead->data;
	//另外赋值第一个结点 ,为了后面找到它并释放 
	StackNode *p=phead;
	//直接更新头节点 
	phead=p->next;
	free(p);
	return phead;
} 
void StackPrint(StackNode* phead)
{
	StackNode* pos =phead;
	while(pos!=NULL)
	{
		printf("%d->",pos->data);
		pos = pos->next;
	}
	printf("NULL\n");
 } 
int main()
{
	StackNode *phead;
	phead=StackNodepush(phead,0);
	phead=StackNodepush(phead,1);
	phead=StackNodepush(phead,2);
	phead=StackNodepush(phead,3);
	StackPrint(phead);
	
	return 0;
} 

Guess you like

Origin blog.csdn.net/m0_59844149/article/details/132168350