Estructura de datos: pila secuencial y pila en cadena

Apilar

La pila es una tabla lineal con Last In Fast Out (Last In Fast Out). Se limita a insertar y eliminar tablas lineales solo al final de la tabla. El extremo que permite la inserción y eliminación se llama la parte superior de la pila.

Diagrama de pila

Inserte la descripción de la imagen aquí

Variación de apilado y fuera de apilamiento

Los elementos de la pila más avanzada no necesariamente aparecen en último lugar, porque la pila restringe las posiciones de inserción y eliminación de la tabla lineal, y no limita el tiempo para que los elementos entren y salgan, es decir, cuando no todos los elementos se insertan en la pila. , El elemento que va primero también puede aparecer, siempre que sea el elemento superior de la pila.

Por ejemplo, los elementos de números enteros 1, 2 y 3 se insertan en la pila a su vez, y el orden de apilamiento puede ser:

  • El primer tipo, 1, 2, 3 adentro, y luego 3, 2, 1, afuera, orden de pila 321
  • El segundo tipo, 1 entrada, 1 salida, 2 entradas, 2 salidas, 3 entradas, 3 salidas, fuera de orden de pila 123
  • El tercer tipo, 1 entrada, 2 entradas, 2 salidas, 1 salida, 3 entradas, 3 salidas, fuera de orden de pila 213
  • El cuarto tipo, 1 entrada, 1 salida, 2 entradas, 3 entradas, 3 salidas, 2 salidas, fuera del orden de pila 132
  • El quinto tipo, 1 entrada, 2 entradas, 2 salidas, 3 entradas, 3 salidas, 1 salida, secuencia de apilado 231

Hay 5 órdenes de apilamiento para 3 elementos.

Estructura de almacenamiento secuencial de la pila.

La pila es un caso especial de la tabla lineal. La estructura de almacenamiento secuencial de la pila es en realidad una simplificación del almacenamiento secuencial de la tabla lineal, denominada pila secuencial. La estructura de la pila secuencial es la siguiente:

typedef int ElemType;   /* ElemType类型根据实际情况而定,这里假设为int */  
typedef struct Stack
{
    
    
	Elemtype *elem;
	int top;   /* 用于栈顶指针 */
	int stacksize;  /* 栈的空间大小 */
}SqStack;

Inicialización de la pila secuencial

  1. Abre espacio inicial
  2. Inicializar la parte superior
  3. Inicializar tamaño de pila
void InitStack(PStack st)
{
    
    
	assert(st != NULL);  //确保st不为空指针
			
	st->elem = (ElemType*)malloc(sizeof(ElemType)*STACK_INIT_SIZE);
	st->stacksize = STACK_INIT_SIZE;
	st->top = -1;
}

Expansión secuencial de la pila

  1. Abrir espacio
  2. Actualizar tamaño de pila
static void AppendStack(PStack st)//扩容
{
    
    
	assert(st != NULL);
	
	st->elem = (ElemType*)realloc(st->elem, st->stacksize + sizeof(ElemType)*STACKINCREMENT);
	st->stacksize += STACKINCREMENT;
}

Empuje de la pila secuencial (Empuje)

Inserte la descripción de la imagen aquí
Para la operación de empuje, se hacen realmente tres cosas

  1. Juzga que la pila está llena
  2. Apilar puntero superior más uno
  3. Asignar el elemento recién insertado al espacio superior de la pila
void Push(PStack st, ElemType val)
{
    
    
	assert(st != NULL);
		
	if (st->top == st->stacksize)  //判断栈满
	{
    
    
		AppendStack(st);
	}
	st->top++;  //栈顶指针加一
	st->elem[st->top] = val;  //将新插入元素赋值给栈顶空间
	
}

Pop de pila secuencial (Pop)

Si la pila no está vacía, coloque el elemento superior de la pila en e y disminuya el puntero superior en uno

int Pop(PStack st, ElemType *e)  // 若栈不为空,则弹出栈顶元素给e,栈顶指针减一
{
    
    
	assert(st != NULL);
		
	if (st->top >= 0)
	{
    
    
		*e = st->elem[st->top];
		st->top--;
		return 1;
	}
	return 0;	
}

Destrucción de pila secuencial

void Destory(PStack st)
{
    
    
	assert(st != NULL);

	free(st->elem);
	st->elem = NULL;
	st->stacksize = 0;
}

Vaciado secuencial de pilas

void Clear(PStack st)
{
    
    
	assert(st != NULL);
	
	st->top = 0;
}

La pila de secuencias está vacía

bool IsEmpty(PStack st)
{
    
    
	assert(st != NULL);

	return st->top == -1;
}

Obtenga el elemento superior de la pila secuencial

ElemType GetTop(PStack st)
{
    
    
	assert(st != NULL);
	return st->elem[st->top];
}

Estructura de almacenamiento encadenada de la pila.

La estructura de almacenamiento en cadena de la pila consiste en implementar la pila en un método de lista vinculada, denominado pila en cadena. La
pila en cadena coloca la parte superior de la pila en la cabecera de la lista vinculada única, como se muestra en la siguiente figura: La
Inserte la descripción de la imagen aquí
estructura de la pila en cadena es la siguiente:

typedef struct StackNode  // 栈结点
{
    
    
	ElemType data;
	struct StackNode *next;
}StackNode,*LinkStackPtr;

typedef struct LinkStack  // 链栈
{
    
    
	LinkStackPtr top;
	int count;
}LinkStack;

La mayoría de las operaciones de la pila de cadenas son similares a las de una lista enlazada individualmente, excepto por inserciones y eliminaciones.

Empuje de la pila de cadenas (Empuje)

Suponiendo que el nuevo nodo s cuyo valor de elemento es e se va a insertar en la pila, y top es el puntero de la parte superior de la pila, el diagrama esquemático de la inserción es el siguiente:
Inserte la descripción de la imagen aquí

  1. Asignar el elemento superior de la pila actual al sucesor inmediato del nuevo nodo
  2. Actualice el puntero superior de la pila para que apunte al nuevo elemento
Status Push(LinkStack *LS, ElemType e)
{
    
    
	LinkStackPtr s = (LinkStackPtr)malloc(sizeof(StacNode));
	s->data = e;
	
	s->next = LS->top; //将当前的栈顶元素赋值给新节点的直接后继
	LS->top = s;  //更新栈顶指针,使其指向新元素
	
	LS->count++;
	
	return OK;
}

Pop de la pila de cadenas (Pop)

Suponga que la variable p se usa para almacenar el nodo superior de la pila que se eliminará

  1. Asigne el nodo superior de la pila ap, como se muestra en el paso 1
  2. El puntero superior de la pila se mueve un bit hacia abajo, como se muestra en el paso 2 a continuación.
  3. Liberar nodo p

Inserte la descripción de la imagen aquí

//若栈不为空,则删除栈顶元素,用e返回其值,并返回OK;否则返回ERROR
Status Pop(LinkStack *S, ElemType *e)
{
    
    
	LinkStackPtr p;
	if(StackEmpty(*S))
	{
    
    
		return ERROR;
	}
	*e = S->top->next;
	
	p = S->top; //将栈顶结点赋值给p,如上图步骤1
	S->top = S->top->next;  //栈顶指针下移一位,如上图步骤2
	free(p);  //释放结点p
	S->count--;
	
	return OK;
}

Comparación de pila secuencial y pila en cadena

La complejidad de tiempo del apilamiento y apilamiento de la pila secuencial y la pila en cadena es O (1). Para el rendimiento del espacio, la pila secuencial necesita determinar una longitud fija de antemano, lo que puede causar un desperdicio de espacio de memoria, pero su ventaja es que es fácil de acceder y ubicar, mientras que la pila de cadena requiere que cada elemento tenga un campo de puntero, que también Se agrega algo de sobrecarga de memoria, pero la longitud de la pila se puede desarrollar de manera flexible. Entonces, la diferencia entre ellos es como la diferencia entre una lista secuencial y una lista vinculada.
Si el cambio de elementos durante el uso de la pila es impredecible, a veces pequeño, a veces grande, entonces es mejor usar una pila en cadena; por el contrario, si sus cambios están dentro de un rango controlable, puede usar una pila secuencial

Supongo que te gusta

Origin blog.csdn.net/huifaguangdemao/article/details/108348862
Recomendado
Clasificación