数据结构(C语言)顺序栈

顺序栈的定义

        顺序栈是栈的顺序实现,栈是一种线性数据结构,采用地址连续的存储空间,遵循先进后出(FILO,First-In-Last-Out)的原则。即最后进入栈的元素将首先被弹出,类似于堆叠物品的过程。

顺序栈的特点

  1. 遵循后进先出(FILO)原则。
  2. 利用栈顶指针标识栈顶元素。
  3. 初始化为空栈,随着元素入栈和出栈,栈的大小动态变化。
  4. 常用于需要维护后进先出顺序的问题,如函数调用栈、表达式求值等。

顺序栈的运算

  1. 初始化栈:创建一个空栈。

  2. 入栈:将元素放入栈顶。

  3. 出栈:从栈顶取出元素。

  4. 获取栈顶元素:查看栈顶元素但不移除。

  5. 判空:检查栈是否为空。

  6. 获取栈大小:获取栈中元素的个数。

  7. 清空栈:移除栈中所有元素,使栈为空。

  8. 销毁栈:释放栈的内存。

顺序栈的实现 

定义顺序栈

typedef int DataType;
 
 
typedef struct
{
	DataType *data; /* 堆空间 */
	int maxsize;
	int top;		/* 栈顶指针 */
}SeqStack;

初始化

/* 1. 初始化 */
int init(SeqStack *S, int MaxSize)
{
	/*申请内存空间*/
	S->data = (DataType*)malloc(sizeof(DataType)*MaxSize);
 
	if(!S->data)
	{
		printf("内存申请错误,初始化失败![10001]\n");
		return 10001;
	}
	S->maxsize = MaxSize;
	S->top = -1;
	return 0;
}

入栈

/* 2. 进(入)栈 */
int push(SeqStack *S, DataType x)
{
	/*是否满?*/
	if(full(S))
	{
		printf("栈已满!10002\n");
		return 10002;
	}
 
	S->top++;			/*移动指针*/
	S->data[S->top] = x;/*放入数据*/
	return 0; /*OK*/
}

出栈

/* 3. 出栈 */
int pop(SeqStack *S, DataType *x)
{
	/*是否空?*/
	if(empty(S))
	{
		printf("栈为空!10003\n");
		return 10003;
	}
 
	*x = S->data[S->top];	/*栈顶元素赋值给x*/
	S->top--;				/*移动栈顶指针*/	
 
	return 0;
}

获取栈顶元素

/* 4. 取栈顶元素 */
int get_top(SeqStack *S, DataType *x)
{
	/*是否空?*/
	if(empty(S))
	{
		printf("栈为空!10003\n");
		return 10003;
	}
 
	*x = S->data[S->top];	/*栈顶元素赋值给x*/
 
	return 0;
}

判断栈是否为空 

/* 5. 栈为空?*/
int empty(SeqStack *S)
{
	return (S->top == -1)?1:0;
}

判断栈是否已满 

/* 6. 栈满?*/
int full(SeqStack *S)
{
	return (S->top == S->maxsize - 1)?1:0;
}

 销毁栈

/* 7. 销毁*/
int destroy(SeqStack *S)
{
	free(S->data);
	return 0;
}

 运行结果截图

顺序栈的应用 

十进制转换为二进制

/*十进制转换为二进制*/
int d_to_b(int d)
{
	SeqStack S;
	int b;
 
	/*初始化栈*/
	init(&S,32);
 
	/*d不为0,余数进栈*/
	while(d)
	{
		push(&S, d % 2);
		d /= 2;
	}
	
	/*依次出栈*/
	while(!empty(&S))
	{
		pop(&S,&b);
		printf("%d", b);
	}
 
	/*销毁栈*/
	destroy(&S);
}

后缀表达式计算

/*后缀表达式计算*/
int expression()
{
	SeqStack S;
	int i;
	int op1, op2;	
	int x;
 
	char exp[20]; /*后缀表达式*/
 
	init(&S, 10);
 
	printf("请输入一个后缀表达式(eg. 56+):");
	scanf("%s", exp);
	for(i=0;i<strlen(exp);i++)
	{
		switch(exp[i])
		{
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			/*入栈*/
			push(&S, exp[i]-48);
			printf("%c\n",exp[i]);
			break;
		case '+':
			/*出2个*/
			pop(&S, &op1);
			pop(&S, &op2);
			x = op1 + op2;
			push(&S, x);
			break;
 
		case '*':
			pop(&S, &op1);
			pop(&S, &op2);
			x = op1 * op2;
			push(&S, x);
			break;
		case '-':
			pop(&S, &op1);
			pop(&S, &op2);
			x =  op2- op1;
			push(&S, x);
			break;
		case '/':
			pop(&S, &op1);
			pop(&S, &op2);
			x =  op2/op1;
			push(&S, x);
			break;	
		}
	}
	pop(&S, &x);
	printf("计算结果为:%s = %d\n", exp, x);
	destroy(&S);
}

 

 完整Demo

main.c

#include <stdio.h>
#include "seqstack.c"
#include "welcome.h"
 
 
int main(int argc, char* argv[])
{
	SeqStack S;
	DataType x;
	int maxsize;
	char yn;
	int i,m,n,cmd,d;
;
	for(i=0;i<strlen(welcome);i++)
	{
		printf("%c",welcome[i]);
		for(m=0;m<1000;m++)
			for(n=0;n<1000;n++)
			{
				;
			}
	}
	
		printf("---------顺序栈演示程序-----------\n");
	do
	{
		printf(" 1. 初始化\n");
		printf(" 2. 入栈\n");
		printf(" 3. 出栈\n");
		printf(" 4. 查找栈顶元素\n");
		printf(" 5. 判断栈为是否空\n");
		printf(" 6. 判断栈为是否满\n"); 
		printf(" 7. 销毁栈\n"); 
		printf(" 8. 栈的应用\n");
		printf(" 9. 帮助\n");
		printf("请选择(0~9,0退出):");
		scanf("%d", &cmd);
		switch(cmd)
		{
		case 1:
			printf("请输入栈的最大存储空间(MaxSize):");
			scanf("%d", &maxsize);
			if(!init(&S, maxsize))
			{
				printf("栈已初始化!\n");
			}
			break;
		case 2:
			printf("请输入入栈元素:x=");
			scanf("%d", &x);
			if(!push(&S, x))
			{
				printf("元素【%d】已入栈!\n", x);
 
			}
			break;
		case 3:
			printf("确定要出栈(出栈后数据不可恢复,y|n,n)?");
			fflush(stdin);
			scanf("%c", &yn);
			if(yn == 'y' || yn == 'Y')
			{
				if(!pop(&S, &x))
				{
					printf("栈顶元素【%d】已出栈!\n", x);
				}
			}
 
			break;
		case 4:
			if(!get_top(&S,&x)){
				printf("查找到栈顶元素[%d]\n",x); 
			}
			break; 
		case 5:
			if(empty(&S)){
				printf("栈为空!\n"); 
			}else{
				printf("栈内存在元素\n"); 
			}
			break;
		case 6:
			if(full(&S)){
				printf("栈满!\n"); 
			}else{
				printf("栈未满\n"); 
			}
			break;
		case 7:
			destroy(&S);
			printf("栈已销毁\n"); 	
			break;
		case 8:
			do
			{
				printf("----------8.栈的应用------------\n");
				printf(" 1. 十进制转换为二进制\n");
				printf(" 2. 后缀表达式计算\n");			
				printf(" 0. 返回\n");
				printf("请选择:");
				scanf("%d", &cmd);
 
				if(cmd == 1)
				{
					printf("请输入一个十进制数:");
					scanf("%d", &d);
					printf("二进制为:");
					d_to_b(d);
					printf("\n");
				}
 
				if(cmd == 2)
				{
					expression();
				}
			}while(cmd!=0);
			cmd = -1;
			break;
		case 9:
			printf(" 本程序为栈的演示程序,由陈勇豪设计开发,程序完成了栈的基本功能!\n");		
		default:
			printf("输入选项不存在\n"); 		
		}
 
	}while(cmd!=0);
 
	return 0;
}
/*十进制转换为二进制*/
int d_to_b(int d)
{
	SeqStack S;
	int b;
 
	/*初始化栈*/
	init(&S,32);
 
	/*d不为0,余数进栈*/
	while(d)
	{
		push(&S, d % 2);
		d /= 2;
	}
	
	/*依次出栈*/
	while(!empty(&S))
	{
		pop(&S,&b);
		printf("%d", b);
	}
 
	/*销毁栈*/
	destroy(&S);
}
 
 
/*后缀表达式计算*/
int expression()
{
	SeqStack S;
	int i;
	int op1, op2;	
	int x;
 
	char exp[20]; /*后缀表达式*/
 
	init(&S, 10);
 
	printf("请输入一个后缀表达式(eg. 56+):");
	scanf("%s", exp);
	for(i=0;i<strlen(exp);i++)
	{
		switch(exp[i])
		{
		case '0':
		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			/*入栈*/
			push(&S, exp[i]-48);
			printf("%c\n",exp[i]);
			break;
		case '+':
			/*出2个*/
			pop(&S, &op1);
			pop(&S, &op2);
			x = op1 + op2;
			push(&S, x);
			break;
 
		case '*':
			pop(&S, &op1);
			pop(&S, &op2);
			x = op1 * op2;
			push(&S, x);
			break;
		case '-':
			pop(&S, &op1);
			pop(&S, &op2);
			x =  op2- op1;
			push(&S, x);
			break;
		case '/':
			pop(&S, &op1);
			pop(&S, &op2);
			x =  op2/op1;
			push(&S, x);
			break;	
		}
	}
	pop(&S, &x);
	printf("计算结果为:%s = %d\n", exp, x);
	destroy(&S);
}

seqstack.c

#include "seqstack.h"
 
 
/* 1. 初始化 */
int init(SeqStack *S, int MaxSize)
{
	/*申请内存空间*/
	S->data = (DataType*)malloc(sizeof(DataType)*MaxSize);
 
	if(!S->data)
	{
		printf("内存申请错误,初始化失败![10001]\n");
		return 10001;
	}
	S->maxsize = MaxSize;
	S->top = -1;
	return 0;
}
 
 
/* 2. 进(入)栈 */
int push(SeqStack *S, DataType x)
{
	/*是否满?*/
	if(full(S))
	{
		printf("栈已满!10002\n");
		return 10002;
	}
 
	S->top++;			/*移动指针*/
	S->data[S->top] = x;/*放入数据*/
	return 0; /*OK*/
}
 
/* 3. 出栈 */
int pop(SeqStack *S, DataType *x)
{
	/*是否空?*/
	if(empty(S))
	{
		printf("栈为空!10003\n");
		return 10003;
	}
 
	*x = S->data[S->top];	/*栈顶元素赋值给x*/
	S->top--;				/*移动栈顶指针*/	
 
	return 0;
}
 
/* 4. 取栈顶元素 */
int get_top(SeqStack *S, DataType *x)
{
	/*是否空?*/
	if(empty(S))
	{
		printf("栈为空!10003\n");
		return 10003;
	}
 
	*x = S->data[S->top];	/*栈顶元素赋值给x*/
 
	return 0;
}
 
/* 5. 栈为空?*/
int empty(SeqStack *S)
{
	return (S->top == -1)?1:0;
}
 
/* 6. 栈满?*/
int full(SeqStack *S)
{
	return (S->top == S->maxsize - 1)?1:0;
}
 
 
/* 7. 销毁*/
int destroy(SeqStack *S)
{
	free(S->data);
	return 0;
}

seqstack.h

typedef int DataType;
 
 
typedef struct
{
	DataType *data; /* 堆空间 */
	int maxsize;
	int top;		/* 栈顶指针 */
}SeqStack;
 
 
/* 1. 初始化 */
int init(SeqStack *S, int MaxSize);
 
/* 2. 进(入)栈 */
int push(SeqStack *S, DataType x);
 
/* 3. 出栈 */
int pop(SeqStack *S, DataType *x);
 
/* 4. 取栈顶元素 */
int get_top(SeqStack *S, DataType *x);
 
/* 5. 栈为空?*/
int empty(SeqStack *S);
 
/* 6. 栈满?*/
int full(SeqStack *S);
 
/* 7. 销毁*/
int destroy(SeqStack *S);

welcome.h

char welcome[] = "\n\
                               \n\                      
                                  IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII\n\                              
                                  IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII\n\                              
                                  IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII\n\                              
                                  IIIII    IIIIIIIIIII     IIIIIII\n\                              
                                  IIIIIII     IIIIIIIIII   IIIIIII\n\                              
                                  IIIIIIIII     IIIIIIIIIIIIIIIIII\n\                              
                                  IIIIIIIIIII       IIIIIIIIIIIIII\n\                              
                                  IIIIIIIIIIIII        IIIIIIIIIII\n\                              
                                  IIIIIIIIIIIIIII         IIIIIIII\n\                              
                                  IIIIIIIIIIIIIIIII         IIIIII\n\                              
                                  IIIII    IIIIIIIIIII        IIII\n\                              
                                  IIIII     IIIIIIIIIII      IIIII\n\                              
                                  IIIII      IIIIIIIIIII    IIIIII\n\                              
                                  IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII\n\                              
                                  IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII\n\n\n\                                                                                                               
      IIIIIIIII.           .IIIIIIIII.       IIIIIIIIIIIII          I            .IIIIIII.\n\      
      III      III        III       III      I.   III   .I         III          III    III\n\      
      III       III      III         III          III             II II               III\n\       
      III        III     III          II          III            II  III             III\n\        
      III        III     III          II          III           II    III           III\n\         
      III       III       III        II           III          II      III         III\n\          
      III      II          IIII     II            III          IIIIIIIIIII        III    .I\n\     
      IIIIIIIIII             IIIIIII              III          II       II       IIIIIIIIII\n\n";

小结 

        顺序栈是一种利用顺序存储结构实现的栈,遵循后进先出(FILO)原则。这种数据结构非常简单而高效,适用于多种应用场景。它的关键操作包括入栈、出栈、查看栈顶元素、判空、获取栈大小、清空栈和销毁栈。顺序栈操作高效,但容量通常有限,需注意动态扩展。它在括号匹配、表达式求值、历史记录、算法等方面有广泛应用。

参考文献:《数据结构(C语言版)》李刚、刘万辉主编,高等教育出版社。OpenAI

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值