Capítulo 4: 3. Estructura de almacenamiento encadenado de la pila y su implementación

Este artículo hace referencia a la "Estructura de datos de Dahua", gracias al autor, el Sr. Cheng Jie.

Uno:
La estructura de almacenamiento en cadena de la pila, denominada pila de cadena,

Dado que la lista enlazada individualmente tiene un puntero principal, y el puntero superior de la pila también es necesario, se puede combinar en uno;
como se muestra a continuación, coloque la parte superior de la pila en la cabecera de la lista enlazada individualmente.
Inserte la descripción de la imagen aquí

Dos:
para la pila en cadena, básicamente no hay pila llena, a menos que la memoria del sistema esté llena;
para la pila vacía, la definición original de la lista enlazada es que el puntero principal está vacío, entonces la pila en cadena está realmente cuando top = = NULO;

Tres: el código de estructura de la pila de cadenas;

/* 链栈结构 */
typedef struct StackNode
{
    
    
    SElemType data;
    struct StackNode *next;
}StackNode,*LinkStackPtr;

typedef struct
{
    
    
    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 la inserción y eliminación.

Cuatro: La estructura de almacenamiento en cadena de la operación de
empuje de pila ; para la operación de empuje de la pila de cadena, suponiendo que el nuevo nodo con el valor del elemento e es sy top es el puntero de la parte superior de la pila,
la operación de empuje es como sigue:

Inserte la descripción de la imagen aquí

/* 插入元素e为新的栈顶元素 */
Status Push(LinkStack *S,SElemType e)
{
    
    
    LinkStackPtr s=(LinkStackPtr)malloc(sizeof(StackNode)); 
    s->data=e; 
    s->next=S->top;	/* 把当前的栈顶元素赋值给新结点的直接后继,见图中① */
    S->top=s;  		/* 将新的结点s赋值给栈顶指针,见图中② */
    S->count++;
    return OK;
}

Cinco: la estructura
de almacenamiento en cadena de la operación stack-pop ; la operación pop de la pila en cadena es una operación simple de tres frases.
Suponiendo que la variable p se usa para almacenar el nodo en la parte superior de la pila que se va a eliminar, mueva el puntero de la parte superior de la pila un bit hacia abajo y finalmente suelte p, de la siguiente manera:
Inserte la descripción de la imagen aquí

/* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
Status Pop(LinkStack *S,SElemType *e)
{
    
     
    LinkStackPtr p;
    if(StackEmpty(*S))
    	return ERROR;
    *e=S->top->data;
    p=S->top;				/* 将栈顶结点赋值给p,见图中③ */
    S->top=S->top->next;    /* 使得栈顶指针下移一位,指向后一结点,见图中④ */
    free(p);                /* 释放结点p */        
    S->count--;
    return OK;
}

Seis:
El progreso de las operaciones push y pop de la pila en cadena es muy simple, sin operaciones de bucle, y la complejidad del tiempo es O (1).

Código:

/*
 
本篇文章参考的是《大话数据结构》,感谢作者程杰先生。

*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>

#include "bigtalk_data_structure.h"


#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */

typedef int Status; 
typedef int SElemType; /* SElemType类型根据实际情况而定,这里假设为int */


/* 链栈结构 */
typedef struct StackNode
{
    
    
        SElemType data;
        struct StackNode *next;
}StackNode,*LinkStackPtr;


typedef struct
{
    
    
        LinkStackPtr top;
        int count;
}LinkStack;

static Status visit(SElemType c)
{
    
    
	printf("%d ",c);
	return OK;
}

/*  构造一个空栈S */
static Status InitStack(LinkStack *S)
{
    
     
	S->top = (LinkStackPtr)malloc(sizeof(StackNode));
	
	if(S->top == NULL)
	{
    
    
		return ERROR;
	}
	
	S->top = NULL;
	S->count = 0;
	return OK;
}

/* 把S置为空栈 */
static Status ClearStack(LinkStack *S)
{
    
     
	LinkStackPtr p,q;
	p = S->top;
	
	while(p != NULL)
	{
    
      
		q = p;
		p = p->next;
		free(q);
	} 
	
	S->count=0;
	
	return OK;
}

/* 若栈S为空栈,则返回TRUE,否则返回FALSE */
static Status StackEmpty(LinkStack S)
{
    
     
	if (S.count == 0)
	{
    
    
		return TRUE;
	}
	else
	{
    
    
		return FALSE;
	}
}

/* 返回S的元素个数,即栈的长度 */
static int StackLength(LinkStack S)
{
    
     
	return S.count;
}

/* 若栈不空,则用e返回S的栈顶元素,并返回OK;否则返回ERROR */
static Status GetTop(LinkStack S,SElemType *e)
{
    
    
	if (S.top == NULL)
	{
    
    
		return ERROR;
	}
	else
	{
    
    
		*e = S.top->data;
	}

	return OK;
}

/* 插入元素e为新的栈顶元素 */
static Status Push(LinkStack *S,SElemType e)
{
    
    
	LinkStackPtr s = (LinkStackPtr)malloc(sizeof(StackNode)); 
	if (s == NULL)
	{
    
    
		return ERROR;
	}
	
	s->data = e;
	
	s->next = S->top;	/* 把当前的栈顶元素赋值给新结点的直接后继,见图中① */
	S->top = s;         /* 将新的结点s赋值给栈顶指针,见图中② */
	S->count++;

	return OK;
}

/* 若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK;否则返回ERROR */
static Status Pop(LinkStack *S,SElemType *e)
{
    
     
	LinkStackPtr p;
	
	if(StackEmpty(*S))
	{
    
    
		return ERROR;
	}
	
	*e = S->top->data;

	p = S->top;					/* 将栈顶结点赋值给p,见图中③ */
	S->top = S->top->next;    /* 使得栈顶指针下移一位,指向后一结点,见图中④ */
	free(p);                   /* 释放结点p */        

	S->count--;

	return OK;
}

static Status StackTraverse(LinkStack S)
{
    
    
	LinkStackPtr p;
	p = S.top;
	
	while(p != NULL)
	{
    
    
		visit(p->data);
		p = p->next;
	}
	printf("\n");
	
	return OK;
}

//栈:栈的链式存储结构
void test_main_4_6()
{
    
    
	printf("[%s:%d]:[yang] ******************* 我是分割线******************* \n",__FUNCTION__,__LINE__);	

	int j;
	LinkStack s;
	int e;
	
	if(InitStack(&s) == OK)
	{
    
    
		for(j = 1;j <= 10;j++)
		{
    
    
			Push(&s,j);
		}
	}

	printf("栈中元素依次为:");
	StackTraverse(s);

	printf("StackLength(s) = %d\n",StackLength(s));
	

	printf("[%s:%d]:[yang] ******************* 我是分割线******************* \n",__FUNCTION__,__LINE__);	

	Pop(&s,&e);
	printf("弹出的栈顶元素 e = %d\n",e);
	printf("StackLength(s) = %d\n",StackLength(s));



	printf("[%s:%d]:[yang] ******************* 我是分割线******************* \n",__FUNCTION__,__LINE__);	

	printf("栈空否:%d(1:空 0:否)\n",StackEmpty(s));

	printf("[%s:%d]:[yang] ******************* 我是分割线******************* \n",__FUNCTION__,__LINE__);	

	GetTop(s,&e);
	printf("栈顶元素 e = %d 栈的长度为 %d\n",e,StackLength(s));

	printf("栈中元素依次为:");
	StackTraverse(s);




	printf("[%s:%d]:[yang] ******************* 我是分割线******************* \n",__FUNCTION__,__LINE__);	

	ClearStack(&s);
	printf("清空栈后,栈空否:%d(1:空 0:否)\n",StackEmpty(s));

	#if 0
	

	#endif

}




impresión:

[main:14]:[yang] ***************************************** 
[test_main_4_6:170]:[yang] ******************* 我是分割线******************* 
栈中元素依次为:10 9 8 7 6 5 4 3 2 1 
StackLength(s) = 10
[test_main_4_6:190]:[yang] ******************* 我是分割线******************* 
弹出的栈顶元素 e = 10
StackLength(s) = 9
[test_main_4_6:198]:[yang] ******************* 我是分割线******************* 
栈空否:0(1:0:)
[test_main_4_6:202]:[yang] ******************* 我是分割线******************* 
栈顶元素 e = 9 栈的长度为 9
栈中元素依次为:9 8 7 6 5 4 3 2 1 
[test_main_4_6:213]:[yang] ******************* 我是分割线******************* 
清空栈后,栈空否:1(1:0:)

Supongo que te gusta

Origin blog.csdn.net/yanghangwww/article/details/110847766
Recomendado
Clasificación