C language data structure - stack and queue of linear table

foreword

Why define the two data structures of stack and queue?
The reason is:
The reason why data structures such as stacks and queues are defined
is because they have two major characteristics :
First: they can save information at various points in the program's running path for backtracking operations or other needs to access the already visited Operations on node information.
For example: The stack is used to solve the maze problem, that is, if the line is blocked, it is necessary to go back to the node that has been visited, and make another choice from that node that is different from the path this time.
Second:
the order of FIFO and FIFO
.
Solve the problem of base conversion, that is: first push the remainder of the ones digit into the stack, then push the remainder of the tens digit into the stack, then the hundreds digit, thousands digit, etc., so that when popping out the stack, the order is reversed, that is: first thousand place, hundreds, then tens, and finally ones.

Table of contents

1. Representation and implementation of stack
2. Representation and implementation of queue

1. Representation and implementation of the stack

1.1 The concept and basic structure of the stack

Stack: A special linear list that only allows insertion and deletion of elements at a fixed end. The end where data insertion and deletion operations are performed is called the top of the stack, and the other end is called the bottom of the stack . The data elements in the stack follow the principle of LIFO (Last In First Out).
Push stack: The insertion operation of the stack is called push/push/push, and the incoming data is at the top of the stack.
Popping: The deletion operation of the stack is called popping. The output data is also on the top of the stack.

insert image description here
insert image description here

1.2 Implementation of the stack

The implementation of the stack can generally be implemented using an array or a linked list . Relatively speaking, the structure of the array is better. Because the cost of inserting data at the end of the array is relatively small.
insert image description here
Schematic diagram of the entry and exit of the chain stack
insert image description here

// 下面是定长的静态栈的结构,实际中一般不实用,所以我们主要实现下面的支持动态增长的栈
typedef int STDataType;
#define N 10
typedef struct Stack
{
    
    
STDataType arr[N];
int top; // 栈顶
}Stack;
// 支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
    
    
STDataType* arr;
int top; // 栈顶
int capacity;  // 容量
}Stack;
// 初始化栈
void StackInit(Stack* ps);
// 入栈
void StackPush(Stack* ps, STDataType data);
// 出栈
void StackPop(Stack* ps);
// 获取栈顶元素
STDataType StackTop(Stack* ps);
// 获取栈中有效元素个数
int StackSize(Stack* ps);
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
int StackEmpty(Stack* ps);
// 销毁栈
void StackDestroy(Stack* ps);

1.2.1 Initialize the stack

//初始化
void StackInit(stack* ps)
{
    
    
	assert(ps);
	ps->arr = (STDataType*)malloc(4 * sizeof(STDataType));
	 if (ps->arr == NULL)
	 {
    
    
		 printf("malloc fail\n");
		 exit(-1);
	 }
	ps->capacity = 4;
	ps->top = 0;

}

1.2.2 Push/Push

//压栈
void StackPush(stack* ps, STDataType x)
{
    
    
	assert(ps);
	if (ps->top == ps->capacity)
	{
    
    
		STDataType* temp= (STDataType*)realloc(ps->arr, ps->capacity *2* sizeof(STDataType));
		if (temp == NULL)
		{
    
    
			printf("realloc fail\n");
			exit(-1);
		}
		else
		{
    
    
			ps->arr = temp;
			ps->capacity *= 2;
		}
	}
	ps->arr[ps->top] = x;
	ps->top++;
}

1.2.3 Pop out

//出栈
void StackPop(stack* ps)
{
    
    
	assert(ps);
	assert(ps->top > 0);
	ps->top--;

}

1.2.4 Get the top element of the stack

//返回栈顶元素
STDataType StackTop(stack* ps)
{
    
    
	assert(ps);
	assert(ps->top > 0);
	return (ps->arr[ps->top - 1]);
}

1.2.5 Get the effective number in the stack

//返回栈顶元素
STDataType StackTop(stack* ps)
{
    
    
	assert(ps);
	assert(ps->top > 0);
	return (ps->arr[ps->top - 1]);
}

1.2.6 Return the number of valid elements in the stack

//栈长
int StackSize(stack* ps)
{
    
    
	assert(ps);

	return ps->top;
}

1.2.7 Short judgment

//判空
bool StackEmpty(stack* ps)
{
    
    
	assert(ps);
	return ps->top == 0;
}

1.2.8 Destroying the stack

//销毁
void StackDestroy(stack* ps)
{
    
    
	assert(ps);
	free(ps->arr);
	ps->arr = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

2 Representation and Implementation of Queue

2.1 The concept and structure of the queue

Queue: A special linear table that only allows inserting data at one end and deleting data at the other end. The queue has a first-in-first-out FIFO (First In First Out ) . The end of the delete operation is called the head of the queue
insert image description here

2.2 Implementation of the queue

insert image description here

// 链式结构:表示队列
typedef struct QListNode
{
    
    
struct QListNode* next;
QDataType data;
}QNode;
// 队列的结构
typedef struct Queue
{
    
    
QNode* head;
QNode* tail;
}Queue;
// 初始化队列
void QueueInit(Queue* pq);
// 队尾入队列
void QueuePush(Queue* pq, QDataType data);
// 队头出队列
void QueuePop(Queue* pq);
// 获取队列头部元素
QDataType QueueFront(Queue* pq);
// 获取队列队尾元素
QDataType QueueBack(Queue* pq);
// 获取队列中有效元素个数
int QueueSize(Queue* pq);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* pq);
// 销毁队列
void QueueDestroy(Queue* pq);

2.2.1 Initialize the queue

//初始化
void QueueInit(Queue* pq)
{
    
    
	assert(pq);
	pq->head = NULL;
	pq->tail = NULL;
}

2.2.2 Enter the queue at the end of the queue

//队尾入
void QueuePush(Queue* pq, QDataType x)
{
    
    
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
    
    
		printf("malloc fail\n");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	if (pq->tail == NULL)
	{
    
    
		pq->tail = newnode;
		pq->head = newnode;
	}
	else
	{
    
    
		pq->tail->next = newnode;
		pq->tail = newnode;


	}

}

2.2.3 Dequeue from the head of the queue

//队头出
void QueuePop(Queue* pq)
{
    
    
	//1.一个
	//2.多个
	assert(pq);
	assert(pq->head);
	if (pq->head->next == NULL)
	{
    
    
		free(pq->head);
		pq->head = pq->tail = NULL;

	}
	else
	{
    
    
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}

2.2.4 Get the head element of the queue

//取队列的队头元素
QDataType QueueFront(Queue* pq)
{
    
    
	assert(pq);
	assert(pq->head);
	return pq->head->data;
}

2.2.5 Get the tail element of the queue

//取队列的队尾元素
QDataType QueueBack(Queue* pq)
{
    
    
	assert(pq);
	assert(pq->head);
	return pq->tail->data;
}

2.2.6 Get the number of effective elements in the queue

//返回队列长度
int QueueSize(Queue* pq)
{
    
    
	assert(pq);
	int size = 0;
	QNode* cur = pq->head;
	while (!cur)
	{
    
    
		size++;
		cur = cur->next;
	}
	return size;
}

2.2.7 Short judgment

//判空
bool QueueEmpty(Queue* pq)
{
    
    
	assert(pq);
	return pq->head == NULL;
}

2.2.8 Destroy the queue

//销毁队列
void QueueDestroy(Queue* pq)
{
    
    
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
    
    
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;

}

Guess you like

Origin blog.csdn.net/weixin_63181097/article/details/130020705