[Estructura de datos] Pila y cola

1 pila

1.1 El concepto y la estructura de la pila

Pila: una lista lineal especial que solo permite la inserción y eliminación de elementos en un extremo fijo. El extremo donde se realizan las operaciones de inserción y eliminación de datos se denomina parte superior de la pila, y el otro extremo se denomina parte inferior de la pila . Los elementos de datos en la pila siguen el principio de LIFO (Last In First Out).

Empujar pila: la operación de inserción de la pila se llama empujar/empujar/empujar, y los datos entrantes se encuentran en la parte superior de la pila .

Popping: La operación de eliminación de la pila se llama popping. Los datos de salida también se encuentran en la parte superior de la pila .

1.2 Implementación de la pila

La implementación de la pila generalmente se puede implementar usando una matriz o una lista enlazada.Relativamente hablando, la estructura de la matriz es mejor. Porque el costo de insertar datos al final de la matriz es relativamente pequeño.

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>

//支持动态增长的栈
typedef int STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;//栈顶
	int capacity;//容量
}ST;

//初始化栈
void STInit(ST* ps);
//销毁栈
void STDestroy(ST* ps);
//入栈
void STPush(ST* ps, STDataType x);
//出栈
void STPop(ST* ps);
//获取栈顶元素
STDataType STTop(ST* ps);
//获取栈中有效元素个数
int STSize(ST* ps);
//检测栈是否为空,如果为空返回非零结果,如果不为空返回0
bool STEmpty(ST* ps);
void STInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

void STDestroy(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}

void STPush(ST* ps, STDataType x)
{
	assert(ps);
	if (ps->top == ps->capacity)
	{
		int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a, sizeof(STDataType) * newCapacity);
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = newCapacity;
	}
	ps->a[ps->top] = x;
	ps->top++;
}

void STPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	ps->top--;
}

STDataType STTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	return ps->a[ps->top - 1];
}

int STSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

bool STEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}

2 colas

2.1 El concepto y la estructura de la cola

Queue: Una tabla lineal especial que solo permite insertar datos en un extremo y borrar datos en el otro extremo.La cola sigue el principio de FIFO (primero en entrar, primero en salir).

Poner en cola: El final de la operación de inserción se llama el final de la cola .

Fuera de la cola: el final de la operación de eliminación se denomina cabeza de la cola .

2.2 Implementación de la cola

Las colas también se pueden implementar en la estructura de arreglos y listas enlazadas. Es mejor usar la estructura de listas enlazadas, porque si se usa la estructura de arreglos, la eficiencia de eliminar la cola y generar datos en la cabecera del arreglo será relativamente bajo.

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>

//链式结构:表示队列
typedef int QDataType;
typedef struct QueueNode
{
	struct QueueNode* next;
	QDataType data;
}QNode;

//队列的结构
typedef struct Queue
{
	QNode* head;
	QNode* tail;
	int size;
}Que;

//初始化队列
void QueueInit(Que* pq);
//销毁队列
void QueueDestroy(Que* pq);
//队尾入队列
void QueuePush(Que* pq, QDataType x);
//队头出队列
void QueuePop(Que* pq);
//获取队列头部元素
QDataType QueueFront(Que* pq);
//获取队列队尾元素
QDataType QueueBack(Que* pq);
//检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Que* pq);
//获取队列中有效元素个数
int QueueSize(Que* pq);
void QueueInit(Que* pq)
{
	assert(pq);
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

void QueueDestroy(Que* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
	pq->size = 0;
}

void QueuePush(Que* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	if (pq->tail == NULL)
	{
		pq->head = pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	pq->size++;
}

void QueuePop(Que* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	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;
	}
	pq->size--;
}

QDataType QueueFront(Que* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->head->data;
}

QDataType QueueBack(Que* pq)
{
	assert(pq);
	assert(!QueueEmpty(pq));
	return pq->tail->data;
}

bool QueueEmpty(Que* pq)
{
	assert(pq);
	return pq->head == NULL;
}

int QueueSize(Que* pq)
{
	assert(pq);
	return pq->size;
}

Además, ampliemos para entender que en la práctica, a veces usamos una cola llamada cola circular. Por ejemplo, cuando el curso de sistema operativo explique el modelo de consumo del productor, se utilizará la cola circular. Una cola circular se puede implementar utilizando una matriz o una lista enlazada circular.


fin del articulo

Supongo que te gusta

Origin blog.csdn.net/m0_73156359/article/details/132281611
Recomendado
Clasificación