<Estructura de datos> Implementación de pila

contenido

prefacio

       concepto de pila

       estructura de pila

Implementación de pila

       Crear estructura de pila

       inicializar pila

       destruir pila

       empujar hacia la pila

       estallido

       Obtener el elemento superior de la pila

       Obtener el número de elementos válidos en la pila

       Comprobar si la pila está vacía

codigo total

       Archivo Stack.h

       Archivo Stack.c

       Archivo de prueba.c


prefacio

concepto de pila

  • Pila: una lista lineal especial que permite la inserción y eliminación de elementos solo en un extremo fijo. Un extremo donde se realizan la 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 LIFO (último en entrar, primero en salir). Algo así como un cargador de pistola, la última bala cargada siempre se dispara primero, a menos que el arma esté rota.
  • Empujar pila: La operación de inserción de la pila se llama empujar/empujar/empujar. (Los datos entrantes están en la parte superior de la pila)
  • Pop: La eliminación de la pila se llama pop. (Los datos de salida también están en la parte superior de la pila)

Darse cuenta:

1. Las llamadas a funciones también tienen pilas ¿Hay alguna diferencia entre estas dos pilas?

Por supuesto hay diferencias. La llamada a la función llamará al marco de la pila, y también hay una pila en la memoria. Cuando se ejecuta el programa, la función debe ejecutarse. Las variables locales, los parámetros, los valores devueltos, etc. en la función deben almacenarse en el marco de pila de funciones.

Las dos pilas no tienen nada que ver entre sí, una es la pila en la estructura de datos. La otra es un área de memoria dividida en el sistema operativo, llamada pila, que se utiliza para crear un marco de pila cuando se llama a una función. Aunque no hay conexión en la naturaleza, todos se ajustan a la regla del último en entrar, el primero en salir.

2. Suponga que la secuencia de apilamiento es: 1 2 3 4, entonces la secuencia emergente debe ser: 4 3 2 1?

por supuesto no. Aunque las reglas son claramente LIFO, esto es relativamente hablando. Si se dice que cada vez que entra uno y luego se suelta uno, y luego continúa empujando la pila, ¿no se ajusta también al último en entrar primero? fuera de la regla? Al igual que en el ejemplo anterior, no sorprende que digas que el orden de apilamiento es 1 2 3 4. Cada vez que ingresas uno, uno sale y otro entra, lo que también se ajusta a las reglas. También es posible empujar dos a la pila y luego entrar y salir de nuevo, como 2 1 4 3.

estructura de pila

Implementación de pila

Crear estructura de pila

  • Archivo Stack.h:
//创建栈结构
typedef int STDataType;
typedef struct Stack
{
	STDataType* a; //存储数据
	int top; //栈顶的位置
	int capacity; //容量
}ST;

inicializar pila

  • Pensamiento:

La inicialización es relativamente simple, después de aprender la tabla de secuencia anterior, es muy fácil inicializar la pila

  • Archivo Stack.h:
//初始化栈
void StackInit(ST* ps);
  • Archivo Stack.c:
//初始化栈
void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}
  • Darse cuenta:

​​​Es intencional establecer la parte superior en 0 al inicializar aquí. En primer lugar, se marcó cuando se creó la estructura de la pila arriba. top se usa para registrar la posición de la parte superior de la pila. Dado que es la posición de la parte superior de la pila, cuando la parte superior se inicializa en 0, puede poner los datos directamente en la pila y luego top++ , pero cuando top se inicializa en -1, top necesita ++ para poner los datos primero, porque los datos no se pueden poner en una posición en la que un número negativo no pertenezca a la pila. La siguiente figura muestra el proceso:

 Este artículo usa top = 0 como ejemplo

destruir pila

  • Pensamiento:

El espacio de memoria abierto dinámicamente debe liberarse, free puede establecerse en vacío y el resto de los datos se establece en 0.

  • Archivo Stack.h:
//销毁栈
void StackDestory(ST* ps);
  • Archivo Stack.c:
//销毁栈
void StackDestory(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

empujar hacia la pila

  • Ideas:

El artículo anterior ha enfatizado que top se inicializa a 0, por lo que debe insertarse directamente en los datos y top ++, pero antes de esto, es necesario juzgar si el espacio es suficiente.Cuando top = capacidad, la pila está llena, entonces realloc necesita ser expandido.

  • Archivo Stack.h:
//压栈
void StackPush(ST* ps, STDataType x);
  • Archivo Stack.c:
//压栈
void StackPush(ST* ps, STDataType x)
{
	assert(ps);
	//如果栈满了,考虑扩容
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; //检测容量
		ps->a = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
		if (ps->a == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		ps->capacity = newcapacity; //更新容量
	}
	ps->a[ps->top] = x;//将数据压进去
	ps->top++;//栈顶上移
}

estallido

  • Ideas:

Antes de abrir la pila, asegúrese de que la parte superior no esté vacía y que la condición para que la parte superior no esté vacía sea superior>0, por lo que también debe afirmar que la parte superior>0 y luego mover directamente la parte superior de la pila hacia abajo. eso es todo. Similar a la idea de una tabla de secuencia.

  • Archivo Stack.h:
//出栈
void StackPop(ST* ps);
  • Archivo Stack.c:
//出栈
void StackPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	ps->top--;
}

Obtener el elemento superior de la pila

  • Ideas:

En primer lugar, debemos averiguar quién es el elemento superior de la pila, ¿es la posición superior o la posición top-1? Obviamente, la posición top-1 es el elemento superior de la pila, porque se señaló claramente que top era 0 durante la inicialización anterior, y los datos se colocaron directamente en la pila cuando se empujaron. el subíndice de datos es 0, y luego + +top y luego empuja otros datos, se puede ver que el elemento superior de la pila es la posición del subíndice top-1.

  • Archivo Stack.h:
//访问栈顶数据
STDataType StackTop(ST* ps);
  • Archivo Stack.c:
//访问栈顶数据
STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	return ps->a[ps->top - 1]; //top-1的位置才为栈顶的元素
}

Obtener el número de elementos válidos en la pila

  • Pensamiento:

Como se mencionó anteriormente, el subíndice top-1 es el elemento superior de la pila, ¿significa que hay elementos top-1 en total? Por supuesto que no, aquí está la misma idea que el subíndice de la matriz, el número de elementos debe ser el superior, simplemente devuélvalo directamente.

  • Archivo Stack.h:
//有效元素个数
int StackSize(ST* ps);
  • Archivo Stack.c:
//有效元素个数
int StackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

Comprobar si la pila está vacía

  • Ideas:

Cuando el valor de top es 0, está vacío y el retorno se puede devolver directamente.

  • Archivo Stack.h:
//判空
bool StackEmpty(ST* ps);
  • Archivo Stack.c:
//判空
bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0; //如果top为0,那么就为真,即返回
}
  • Archivo de prueba.c:
void TestStack()
{
	ST st;
	StackInit(&st);
	StackPush(&st, 1);
	StackPush(&st, 2);
	StackPush(&st, 3);
	StackPush(&st, 4);
	while (!StackEmpty(&st))
	{
		printf("%d ", StackTop(&st));
		StackPop(&st);
	}
	printf("\n");
	StackDestory(&st);
}
  • El efecto es el siguiente:

codigo total

Archivo Stack.h

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

//创建栈结构
typedef int STDataType;
typedef struct Stack
{
	STDataType* a; //存储数据
	int top; //栈顶的位置
	int capacity; //容量
}ST;

//初始化栈
void StackInit(ST* ps);

//销毁栈
void StackDestory(ST* ps);

//压栈
void StackPush(ST* ps, STDataType x);

//出栈
void StackPop(ST* ps);

//判空
bool StackEmpty(ST* ps);

//访问栈顶数据
STDataType StackTop(ST* ps);

//有效元素个数
int StackSize(ST* ps);

Archivo Stack.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
//初始化栈
void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}

//销毁栈
void StackDestory(ST* ps)
{
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->top = 0;
}

//压栈
void StackPush(ST* ps, STDataType x)
{
	assert(ps);
	//如果栈满了,考虑扩容
	if (ps->top == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2; //检测容量
		ps->a = (STDataType*)realloc(ps->a, newcapacity * sizeof(STDataType));
		if (ps->a == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		ps->capacity = newcapacity; //更新容量
	}
	ps->a[ps->top] = x;//将数据压进去
	ps->top++;//栈顶上移
}
//出栈
void StackPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	ps->top--;
}

//判空
bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0; //如果top为0,那么就为真,即返回
}

//访问栈顶数据
STDataType StackTop(ST* ps)
{
	assert(ps);
	return ps->a[ps->top - 1]; //top-1的位置才为栈顶的元素
}

//有效元素个数
int StackSize(ST* ps)
{
	assert(ps);
	return ps->top;
}

Archivo de prueba.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"
void TestStack()
{
	ST st;
	StackInit(&st);
	StackPush(&st, 1);
	StackPush(&st, 2);
	StackPush(&st, 3);
	StackPush(&st, 4);
	while (!StackEmpty(&st))
	{
		printf("%d ", StackTop(&st));
		StackPop(&st);
	}
	printf("\n");
	StackDestory(&st);
}
int main()
{
	TestStack();
	return 0;
}

Supongo que te gusta

Origin blog.csdn.net/bit_zyx/article/details/123763458
Recomendado
Clasificación