实验三 栈的应用
一、实验目的
1.掌握栈的抽象数据类型。
2.掌握实现栈的各种操作的算法。
3.理解栈与递归的关系。
4.掌握栈的应用。
二、实验环境
1.硬件:每个学生需配备计算机一台。
2.软件:Windows操作系统+Visual C++。
三、实验要求
1.用C描述栈的每种操作在顺序栈或链栈上的实现。
2.将初始化栈、判断栈是否非空、入栈、出栈、十进制到二进制的转换分别定义为5个子函数,通过主函数实现对上述子函数的调用。
四、实验内容
1.实现顺序栈的各种基本运算
在实现顺序栈各种基本运算的基础上,设计主程序,完成如下功能:
(1)初始化栈s。
(2)判断栈s是否为空。
(3)依次将6,3,8,10元素进栈s。
(4)判断栈s是否为空。
(5)输出栈序列。
(6)判断栈s是否为空。
(7)释放栈s。
实现程序:
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 50
typedef int ElemType;
//定义栈的类型
typedef struct{
ElemType data[MaxSize];
int top;
}SqStack;
//初始化栈
void IniStack(SqStack *&s){
s=(SqStack *)malloc(sizeof(SqStack));
s->top=-1;
}
//判断栈是否为空
bool StackEmpty(SqStack *s){
return(s->top==-1);
}
//进栈
bool Push(SqStack *&s,ElemType e)
{
if(s->top==MaxSize-1)
{
return false;
}
s->top++;
s->data[s->top]=e;
return true;
}
//出栈
bool Pop(SqStack *&s,ElemType &e)
{
if(s->top==-1)
{
return false;
}
e=s->data[s->top];
s->top--;
return true;
}
//销毁栈
void DestroyStack(SqStack *&s)
{
free(s);
}
//取栈顶元素
bool GetTop(SqStack *s,ElemType &e)
{
if(s->top==-1)
return false;
e=s->data[s->top];
return true;
}
//主函数
void main()
{
ElemType e;
SqStack *s;
printf("(1)初始化栈s");
IniStack(s);
printf("\n(2)判断栈s为");
printf("%s\n",(StackEmpty(s)?"空":"非空"));
printf("(3)依次将6,3,8,10元素进栈s");
int a[]={6,3,8,10};
int i;
for(i=0;i<4;i++)
{
Push(s,a[i]);
}
printf("\n(4)判断栈s为");
printf("%s\n",(StackEmpty(s)?"空":"非空"));
printf("(5)输出栈序列");
while(!StackEmpty(s))
{
Pop(s,e);
printf("%3d",e);
}
printf("\n(6)判断栈s为");
printf("%s\n",(StackEmpty(s)?"空":"非空"));
printf("(7)释放栈s\n");
DestroyStack(s);
}
运行结果:
测试结果:
通过!
2.实现链栈的各种基本运算
在实现链栈各种基本运算的基础上,设计主程序,完成上题1的7个操作。
实现程序:
#include<stdio.h>
#include<malloc.h>
typedef int ElemType;
//定义栈的类型
typedef struct linknode{
ElemType data;
struct linknode *next;
}LinkStNode;
//初始化链栈
void InitStack(LinkStNode *&s)
{
s=(LinkStNode *)malloc(sizeof(LinkStNode));
s->next=NULL;
}
//销毁链栈
void DestroyStack(LinkStNode *&s)
{
LinkStNode *p=s->next;
while(p!=NULL)
{
free(s);
s=p;
p=p->next;
}
free(s);
}
//判断栈是否为空
bool StackEmpty(LinkStNode *s)
{
return(s->next==NULL);
}
//进栈
void Push(LinkStNode *&s,ElemType e)
{
LinkStNode *p;
p=(LinkStNode *)malloc(sizeof(LinkStNode));
p->data=e;
p->next=s->next;
s->next=p;
}
//出栈
bool Pop(LinkStNode *&s,ElemType &e)
{
LinkStNode *p;
if(s->next==NULL)
return false;
p=s->next;
e=p->data;
s->next=p->next;
free(p);
return true;
}
//取栈顶元素
bool GetTop(LinkStNode *s,ElemType &e)
{
if(s->next==NULL)
return false;
e=s->next ->data;
return true;
}
//主函数
void main()
{
ElemType e;
LinkStNode *s;
printf("栈链s的基本运算如下\n");
printf("(1)初始化栈s\n");
InitStack(s);
printf("(2)栈为%s\n",(StackEmpty(s)?"空":"非空"));
printf("(3)依次将6,3,8,10元素进栈s\n");
Push(s,6);
Push(s,3);
Push(s,8);
Push(s,10);
printf("(4)栈为%s\n",(StackEmpty(s)?"空":"非空"));
printf("(5)输出栈序列");
while(!StackEmpty(s))
{
Pop(s,e);
printf("%d\t",e);
}
printf("\n");
printf("(6)栈为%s\n",(StackEmpty(s)?"空":"非空"));
printf("(7)释放栈s");
DestroyStack(s);
}
运行结果:
测试结果:
通过!
3.栈的应用
(1)设计算法,利用顺序栈判断一个字符串是否为对称串。
实现程序:
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define MaxSize 100
typedef char ElemType;
//定义栈指针
typedef struct {
char data[MaxSize];
int top;
}SqStack;
//初始化栈
void IniStack(SqStack *&s){
s=(SqStack *)malloc(sizeof(SqStack));
s->top=-1;
}
//进栈
bool Push(SqStack *&s,ElemType e)
{
if(s->top==MaxSize-1)
{
return false;
}
s->top++;
s->data[s->top]=e;
return true;
}
//出栈
bool Pop(SqStack *&s,ElemType &e)
{
if(s->top==-1)
{
return false;
}
e=s->data[s->top];
s->top--;
return true;
}
//销毁栈
void DestroyStack(SqStack *&s)
{
free(s);
}
//判断是否对称的函数
bool symmery(SqStack *&s,char str[])
{
char e;
for(int i=0;str[i]!='\0';i++)
{
Push(s,str[i]);
}
for(int j=0;str[j]!='\0';j++)
{
Pop(s,e);
if(e!=str[j])
{
DestroyStack(s);
printf("该字符串不是对称的\n");
return false;
}
}
DestroyStack(s);
printf("该字符串是对称的\n");
return true;
}
//主函数
void main()
{
SqStack *s;
IniStack(s);
printf("请输入字符串:");
char st[10];
gets(st); //从键盘获取字符串给str数组;
symmery(s,st);
}
运行结果:
测试结果:
通过!
(2)设计算法,判断输入的表达式中括号是否配对。
实现程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MaxSize 50
typedef char ElemType;
//定义栈的类型
typedef struct
{
ElemType data[MaxSize];
int top;
}SqStack;
//初始化栈
void IniStack(SqStack *&s){
s=(SqStack *)malloc(sizeof(SqStack));
s->top=-1;
}
//判断栈是否为空
bool StackEmpty(SqStack *s){
return(s->top==-1);
}
//进栈
bool Push(SqStack *&s,ElemType e)
{
if(s->top==MaxSize-1)
{
return false;
}
s->top++;
s->data[s->top]=e;
return true;
}
//出栈
bool Pop(SqStack *&s,ElemType &e)
{
if(s->top==-1)
{
return false;
}
e=s->data[s->top];
s->top--;
return true;
}
//取栈顶元素
bool GetTop(SqStack *s,ElemType &e)
{
if(s->top==-1)
return false;
e=s->data[s->top];
return true;
}
//判断括号是否匹配
int IsBracketMatch(SqStack *&s,char *str)
{
ElemType e = 'c';
for (unsigned int i = 0; i<strlen(str); i++) {
if ((str[i] == '(' || str[i] == '[' || str[i] == '{')) {
Push(s, str[i]);
} else if (str[i] == ')' || str[i] == ']' || str[i] == '}') {
switch (str[i]) {
case ')':
if (GetTop(s,e) && e == '(') {
Pop(s,e);
} else {
return 0;
}
break;
case ']':
if (GetTop(s,e) && e == '[') {
Pop(s,e);
} else {
return 0;
}
break;
case '}':
if (GetTop(s,e) && e == '{') {
Pop(s,e);
} else {
return 0;
}
break;
}
}
}
if (StackEmpty(s)) {
return 1;
}
return 0;
}
void main()
{
SqStack *s;
IniStack(s);
char str[20];
printf("请在英文状态下输入,判断是否为成对的括号");
scanf("%s",str);
if(
IsBracketMatch(s,str))
printf("匹配!\n");
else
printf("不匹配!\n");
}
运行结果:
测试结果:
通过!
(3)设计算法,利用栈将一个十进制数转换为二进制数。
实现程序:
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 50
typedef int ElemType;
//定义栈的类型
typedef struct{
ElemType data[MaxSize];
int top;
}SqStack;
//初始化栈
void IniStack(SqStack *&s){
s=(SqStack *)malloc(sizeof(SqStack));
s->top=-1;
}
//判断栈是否为空
bool StackEmpty(SqStack *s){
return(s->top==-1);
}
//进栈
bool Push(SqStack *&s,ElemType e)
{
if(s->top==MaxSize-1)
{
return false;
}
s->top++;
s->data[s->top]=e;
return true;
}
//出栈
bool Pop(SqStack *&s,ElemType &e)
{
if(s->top==-1)
{
return false;
}
e=s->data[s->top];
s->top--;
return true;
}
//销毁栈
void DestroyStack(SqStack *&s)
{
free(s);
}
//取栈顶元素
bool GetTop(SqStack *s,ElemType &e)
{
if(s->top==-1)
return false;
e=s->data[s->top];
return true;
}
//转换函数
void Math(SqStack *s,int a,ElemType &e)
{
int j=0,n=0;
int b[1000];
do
{
b[j] =a%2;
a=a/2;
j++;
n++;
}
while (a!=0);
for(int i=0;i<n;i++)
{
Push(s,b[i]);
}
printf("二进制数为");
while(!StackEmpty(s))
{
Pop(s,e);
printf("%d",e);
}
}
//主函数
void main()
{
ElemType e;
SqStack *s;
IniStack(s);
int a;
printf("请输入一个十进制数:");
scanf("%d", &a);
Math(s,a,e);
printf("\n");
DestroyStack(s);
}
运行结果:
测试结果:
通过!
六、实验总结
通过本次实验学习了栈的应用,了解了进栈与出栈的顺序。在一些应用中,栈使用起来非常的方便,例如进制转换的实验,输出时无需将数组逆向。在需要将实验结果掉转顺序的实验提高了效率。