顺序栈相关算法

目录

目的

验证顺序存储的栈及其上的基本操作。

内容及要求

  1. 定义顺序栈类。
  2. 实现如下算法:
    1)创建顺序栈;
    2)插入操作:向栈顶压入值为x的元素;
    3)删除操作:弹出栈顶元素,将数据输出在屏幕上;
    4)存取操作:读取栈顶元素,将数据输出在屏幕上;。
  3. 为了增强程序的可读性,程序中要有适当的注释。
  4. 随机给出栈操作指令序列,完成程序验证。例如:(压栈a,压栈b,压栈 c,压栈d,弹栈,弹栈,弹栈,压栈e,弹栈,读栈顶,弹栈。屏幕应输出d,c,b,e,a,a)

实验过程

算法设计、代码编写、程序调试、测试数据设计、测试

算法设计

先编写有关顺序栈操作的各个函数:
InitStack(SqStack &S)
DestroyStack(SqStack &S)
ClearStack(SqStack &S)
StackEmpty(SqStack S)
StackLength(SqStack S)
GetTop(SqStack S, ElemType &e)
Push(SqStack &S, ElemType &e)
Pop(SqStack &S, ElemType &e)
StackTraverse(SqStack S)
之后的八个函数对应主函数中的八项功能,通过选择结构语句确定执行哪项功能。

代码编写

   //头文件 
    #include<stdio.h> 
    #include<string.h> 
    #include<stdlib.h> 
    #include<malloc.h> 

   //宏定义 
    #define TRUE 1 
    #define FALSE 0 
    #define OK 1 
    #define ERROR 0 
    #define INFEASIBLE -1 
    #define OVERFLOW -2 
    #define STACK_INIT_SIZE 100 
    #define STACKINCREMENT 10 
    typedef int ElemType; 
    typedef int Status; 

   //栈的顺序结构表示 
    typedef struct { 
	    ElemType *base; 
	    ElemType *top; 
	    int stacksize; 
		}SqStack; 
		
	//1.构建一个空栈 
	 Status InitStack(SqStack &S) 
	 { 
	   S.base = (ElemType*)malloc(STACK_INIT_SIZE*sizeof(ElemType)); 
	   if (!S.base) 
	      exit(OVERFLOW);//存储分配失败 
		S.top = S.base; 
		S.stacksize = STACK_INIT_SIZE; 
		return OK; 
	} 
	
	//2.销毁栈 
	  Status DestroyStack(SqStack &S) 
	  { 
	    S.top = NULL; 
		S.stacksize = 0; 
		free(S.base); 
		return OK; 
	} 
	
	//3.清空栈 
	Status ClearStack(SqStack &S) 
	{ 
	  S.top = S.base; 
	  return OK; 
	} 
	
	//4.判断栈是否为空 
	Status StackEmpty(SqStack S) 
	{ 
	  if (S.top == S.base) 
	    return ERROR; 
	  else 
	    return TRUE; 
	} 
	
	//5.求栈的长度 
	Status StackLength(SqStack S) 
	{ 
	  if (S.top == S.base) 
	    return FALSE; 
	  else 
	    return (S.top - S.base);//也可以直接返回S.top - S.base 
	} 
	//6.求栈顶元素 
	Status GetTop(SqStack S, ElemType &e) 
	{ 
	  if (S.top == S.base) 
	    return FALSE; 
	  else e = *(S.top - 1); 
	    return e; 
	} 
	
	//7.栈顶插入元素 
	Status Push(SqStack &S, ElemType &e) 
	{ 
	  if (S.top - S.base >= STACK_INIT_SIZE) 
	  { 
	     S.base = (ElemType *)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(ElemType)); 
		 if (!S.base) 
		 { 
		   return false; 
		   } 
		 S.top = S.base + STACK_INIT_SIZE;  //栈底地址可能改变,重新定位栈顶元素 
		 S.stacksize = S.stacksize + STACKINCREMENT; 
		 } 
	  *S.top = e; 
	  S.top++; 
	  return OK; 
	} 
	
	//8.删除栈顶元素 
	Status Pop(SqStack &S, ElemType &e) 
	{ 
	  if (S.top == S.base) 
	  return ERROR; 
	  else 
	  { 
	     S.top--; 
		 e = *S.top;  //实际上此元素并没真正删除,仍在S.top中,但是如果插入元素,就会被更新,就像是删除了一样 
		 return e; } 
	} 
	
	//9.遍历栈 
	Status StackTraverse(SqStack S) 
	{ 
	  if (S.base == NULL) 
	    return ERROR; 
	  if (S.top == S.base) 
	    printf("栈中没有元素……\n"); 
	  ElemType *p; 
	  p = S.top; 
	  while (p > S.base) 
	  { 
	    p--; 
		printf("%d ",*p); 
	  } 
	    return OK; 
	} 
	
	  
	Status two(SqStack S){
		        printf("--本栈是空栈吗??--\n"); 
	            if (StackEmpty(S) == 1) 
	  printf("NO !\n"); 
	  else printf("YES !!!\n");
	} 
	
	Status three(SqStack S){
		        printf("--求出栈的长度--\n"); 
	  int m; 
	  m = StackLength(S); 
	  printf("栈的长度是:\n"); 
	  printf("%d\n",m);   
	}
	
	Status four(SqStack S){
		         printf("遍历输出栈中的所有元素:\n"); 
	  StackTraverse(S); 
	  printf("\n"); 
	}
	
	Status five(SqStack S){
		        printf("--输出栈顶元素--\n"); 
	  int e; 
	  e = GetTop(S, e); 
	  printf("栈顶元素是:\n"); 
	  printf("%d\n",e); 
	}
	
	Status six(SqStack S){
		        printf("--栈顶插入元素--\n"); 
		        int e;  
		         e = GetTop(S, e); 
	  printf("请输入要插入的元素的数值:\n"); 
	  scanf("%d",&e); 
	  Push(S,e); 
	  printf("现在栈中的元素是:\n"); 
	  StackTraverse(S); 
	  printf("\n"); 
	  
	  
	}
	
	Status seven(SqStack S){
		      printf("--栈顶删除元素--\n"); 
		      int e;
	  e = Pop(S,e); printf("被删除的元素是:\n"); 
	  scanf("%d",&e); printf("现在栈中的元素是:\n"); 
	  StackTraverse(S); 
	  printf("\n");  
	  
	  
	}
	
	Status eight(SqStack S){
		        printf("--清空栈--\n"); 
	  ClearStack(S); 
	  printf("现在栈中的元素是:\n"); 
	  StackTraverse(S); 
	  
	}
	
	Status nine(SqStack S){
		printf("--销毁栈--\n"); 
	  if(DestroyStack(S)==1) 
	    printf("销毁栈成功\n"); 
	  else 
	    printf("销毁栈失败\n"); 
	    
	   
	}
	//主函数 
	int main() 
	{ 
	            int e;
	            SqStack S; 
	            printf("构造一个栈……\n"); 
	            InitStack(S); 
	            int i,n ; 
	            printf("输入栈的长度:\n"); 
	            scanf("%d",&n); 
	            for (i = 1; i <= n; i++) 
	  			{ 
	    		  printf("输入栈的第%d个元素\n",i); 
		          ++S.top; 
		          scanf("%d",S.top-1); 
	            } 
	  int choice;
	  while(1){
	  printf("\n\n1:栈的判空\n2:求栈的长度\n3:遍历输出栈\n4:输出栈顶元素\n5:栈顶删除元素\n6:栈顶插入元素\n7:清空栈\n8:销毁栈\n");
	  scanf("%d",&choice);
	  switch(choice){
	  	case 1:two(S);break;
	  	case 2:three(S);break;
	  	case 3:four(S);break;
	  	case 4:five(S);break;
	  	case 5:seven(S);break;
	  	case 6:six(S);break;
	  	case 7:eight(S);break;
	  	case 8:nine(S);break;
	  }
    }
	  return 0; 
	}


程序调试

1.顺序栈的操作main.cpp [Error] ‘S’ was not declared in this scope
进行分析后发现错误是由于并未在函数中声明pos的类型,当把pos声明为int类型时,错误消失。
2.在写主函数时,如果是用void main 的形式,可以不用有返回值,如果是int main或status main 的话,要有返回值,即末尾要有return 语句。
3.在定义栈的时候num 中的元素最好使用int类型的而不是char 类型的,因为这样会简化计算复杂度。

测试数据设计

先输入3,再输入1,2,3,创建一个长度为3的栈;
输入1,进行栈的判空,返回NO;
输入2,求栈的长度,返回3;
输入3,遍历栈,返回1,2,3;
输入4,输出栈顶元素3;
输入5,栈顶插入元素4;
输入6,栈顶删除元素4,剩1,2,3;
输入7,清空栈;
输入8,销毁栈;

结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

程序运行过程有些繁复,还有需要改进的地方。关于遇到的问题,有以下几点:在做表达式的计算的时候,一定要注意何时入栈何时出栈,如果情况判断不清楚就无法得出答案;对于表达式的判错情况,根据题目的情况对每次读入的字符进行判断;分号的忘记问题要加强注意。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值