实验四 栈和队列的基本操作的实现

1.实验目的
熟练掌握栈和队列的抽象数据类型,能在相应的应用问题中正确选用他们,熟练掌握栈和队列的实现方法(顺序和链式)。两种存储结构和基本操作的实现算法,注意空和满的判断条件及他们的描述方法,掌握循环队列和其他顺序结构实现上的不同及解决方法,熟悉各种队列的基本操作在循环队列上的实现。
2.实验内容
(1)用栈实现括号匹配的检验
(2)用栈实现形如a+b@b+a#的中心对称的字符序列的检验。
(3)用队列实现形如a+b@b+a#的中心对称的字符序列的检验。
选择合适的存储结构(顺序栈或者链式栈)表示栈,给出其定义,在上述存储结构上实现栈的基本操作:初始化、置栈空、入栈、出栈、取栈顶元素等。选择合适的存储结构(循环队列)表示队列,解决队列空、队满判断条件相同的矛盾,实现基于循环队列的存储结构的基本操作,初始化、队空(满)判断。入队、出队、取队头元素。求队列长度等,对写出的·算法进行时间复杂度的分析。

#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0 
#define ERROR 0
#define OK 1
#define OVERFLOW 0
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int Status;
typedef char SElemType;
typedef struct {
 SElemType *base;
 SElemType *top;
 int stacksize;
} SqStack;
Status InitStack(SqStack *S) {
 //构造一个空栈,该栈由指针指示
 S->base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));//栈的连续空间分配
 if (!S->base)
  exit(OVERFLOW);//存储分配失败
 S->top = S->base;//空栈,初始化栈顶指针
 S->stacksize = STACK_INIT_SIZE;
 return OK;
}
Status Push(SqStack *S, SElemType e) {
 //插入元素e作为新的栈顶
 if (S->top - S->base >= S->stacksize) {
  //栈满,追加存储空间
  S->base = (SElemType*)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(SElemType));
  if (!S->base)
   exit(OVERFLOW);
  S->top = S->base + S->stacksize;
  S->stacksize += STACKINCREMENT;
 }
 *S->top = e;
 S->top++;
 return OK;
}
SElemType Pop(SqStack *S) {
 //若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR;
 if (S->top == S->base)
 {
  printf("栈空");
  return ERROR;
 }
 return *--S->top;
}
SElemType GetTop(SqStack *S) {
 //若栈不空,则删除S的栈顶元素,并返回OK,否则返回ERRER
 if (S->top == S->base)
 {
  printf("栈空");
  return OK;
 }
 return *(S->top - 1);//取栈顶元素
}
Status StackEmpty(SqStack *S)
{
 if (S->top == S->base)
 {
  // printf("栈空");
  return TRUE;
 }
 else
 {
  // printf("栈非空");
  return FALSE;
 }
}
Status BracketsMatch(SqStack *S)
{
 char c, x;
 c = getchar();
 while (c != '#')
 {
  if (c == '(' || c == '[' || c == '{')
   Push(S, c);//如果接收到的是右括号就把他送进栈中 
  if (c == ')' || c == ']' || c == '}')
  {
   if (StackEmpty(S))
   {
    printf("not match!\n");
    return ERROR;
   }//  情况1:避免出现输入的全是右括号:}])
   x = Pop(S);
   if (!((x == '('&&c == ')') || (x == '['&&c == ']') || (x == '{'&&c == '}')))
   {
    printf("not match!\n");
    return ERROR;
   }//情况2:避免到来的右括号不是所期待的:[)  
  }//if语句结束
  c = getchar();
 }//while循环结束 
 if (StackEmpty(S))
 {
  printf("match!\n");
  return OK;
 }
 else
 {
  printf("not match!\n");
  return ERROR;//情况3:直到最后结束,也没有到来所期待的括号 :([]#
 }
}//BracketsMatch函数结束 
int main()
{
 SqStack S;
 InitStack(&S);
 printf("请输入括号(以#作为结束符):");
 BracketsMatch(&S);
 system("pause");
 return 0;
}

在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define OK 1
#define OVERFLOW 0
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int Status;
typedef char SElemType;
typedef struct {
 SElemType *base;
 SElemType *top;
 int stacksize;
} SqStack;
Status InitStack(SqStack *S) {
 //构造一个空栈,该栈由指针指示
 S->base = (SElemType*)malloc(STACK_INIT_SIZE * sizeof(SElemType));//栈的连续空间分配
 if (!S->base)
  exit(OVERFLOW);//存储分配失败
 S->top = S->base;//空栈,初始化栈顶指针
 S->stacksize = STACK_INIT_SIZE;
 return OK;
}
Status Push(SqStack *S, SElemType e) {
 //插入元素e作为新的栈顶
 if (S->top - S->base >= S->stacksize) {
  //栈满,追加存储空间
  S->base = (SElemType*)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(SElemType));
  if (!S->base)
   exit(OVERFLOW);
  S->top = S->base + S->stacksize;
  S->stacksize += STACKINCREMENT;
 }
 *S->top = e;
 S->top++;
 return OK;
}
Status Pop(SqStack *S) {
 //若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK,否则返回ERROR;
 if (S->top == S->base)
 {
  printf("栈空");
  return ERROR;
 }
 return *--S->top;//--S->top; e=*S->top;
}
SElemType GetTop(SqStack *S) {
 //若栈不空,则删除S的栈顶元素,并返回OK,否则返回ERRER
 if (S->top = S->base)
 {
  // printf("栈空");
  return ERROR;
 }
 return *(S->top - 1);//取栈顶元素
}
Status StackEmpty(SqStack *S) {
 if (S->top == S->base)
 {
  //printf("栈空");
  return TRUE;
 }
 else
 {
  // printf("栈非空");
  return FALSE;
 }
}
Status Match(SqStack *S) {
 char c, x;
 c = getchar();
 while (c != '@') {
  Push(S, c);
  c = getchar();
 }
 c = getchar();
 while (c != '@' && !StackEmpty(S)) { //c不等于中心对称的标记'@'同时S栈还不能是空的
  x = Pop(S);
  if (c == x)
   c = getchar();
  else {
   printf("not match\n");
   return ERROR;
  }
 }
 if (c == '#'&&StackEmpty(S))//为了解决前半部分确实匹配上了,但是"@"后边的部分超过了前边部分的长度
 {
  printf("match!\n");
  return OK;
 }
 else
 {
  printf("not match\n");
  return ERROR;
 }
}
int main()
{
 SqStack S;
 InitStack(&S);
 printf("请输入字符序列,对称中心是'@',以'#'结束!\n");
 Match(&S);
 system("pause");
 return 0;
}

在这里插入图片描述

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ERROR 0
#define OK 1
#define TRUE 1
#define FALSE 0
#define OVERFLOW 0
#define MAXQSIZE 100
typedef int Status;
typedef char QElemType;
typedef struct {
 QElemType *base;
 int front;//指向队列的第一个元素
 int rear;//指向队列的最后一个元素的下一个元素
} SqQueue;
Status InitQueue(SqQueue *Q) {
 //构造一个空队列Q
 Q->base = (QElemType*)malloc(MAXQSIZE * sizeof(QElemType));//
 if (!Q->base)
  exit(OVERFLOW);//存储分配失败
 Q->front = Q->rear = 0;//初始化头指针,尾指针
 return OK;
}
Status EnQueue(SqQueue *Q, QElemType e) {
 //插入元素e作为Q的新的队尾元素
 if ((Q->rear + 1) % MAXQSIZE == Q->front)//队列满
  return ERROR;
 Q->base[Q->rear] = e;//把这个入队列的数保存在头指针指的那个位置,其实他不是一个真正的指针,只不过是为了方便保存元素
 Q->rear = (Q->rear + 1) % MAXQSIZE;//尾指针向前移动一位
 return OK;
}
Status DeQueue(SqQueue *Q, QElemType *e) {
 //若队列不空,则删除Q 的队头元素,用e返回其值,并返回OK否则返回ERROR
 if (Q->front == Q->rear)//队列满
  return ERROR;
 *e = Q->base[Q->front];//出队列时,队头元素先出去
 Q->front = (Q->front + 1) % MAXQSIZE;//头指针向前移动一位 
 return OK;
}
Status DeQueue_rear(SqQueue *Q, QElemType *e) {
 //若队列不空,则删除Q 的队尾元素,用e返回其值,并返回OK否则返回ERROR
 if (Q->front == Q->rear)//队列满 
  return ERROR;
 Q->rear = (Q->rear - 1) % MAXQSIZE;//队尾指针总是指向最后一个元素的下一个元素的位置,因此在删队尾元素时要先把指针向前移动一位 
 *e = Q->base[Q->rear];//然后取出这个元素 
 return OK;
}
Status QueueEmpty(SqQueue Q) {
 if (Q.front == Q.rear)
  return TRUE;
 else
  return FALSE;
}
int QueueLength(SqQueue Q) {
 //返回Q中元素的个数,即队列的长度
 return(Q.rear - Q.front + MAXQSIZE) % MAXQSIZE;
}
Status Match(char*a) {
 char c, b;
 char*p; //定义字符指针变量p 
 p = a;//把字符串数组的首地址赋给p 
 SqQueue Q;//定义队列Q 
 InitQueue(&Q);//初始化队列Q 
 while (*p != '@') {//p当前所指的元素值不是对称中心字符 的标记 
  EnQueue(&Q, *p);//让p所指的字符进队列 
  p++;//p指针指向下一个字符 
 }
 p++;//跳过对称中心标志@,不让他进队列 
 while (*p != '#') { //p当前所指的字符不是队尾结束
  EnQueue(&Q, *p);//继续进队列 
  p++;// p指针后移 
 }
 while (QueueLength(Q) != 0)
 {//循环的条件限制为队列不是空的,从队尾队头分别删除字符进行比较 
  if (!DeQueue(&Q, &b))//取出队头元素,同时检查是否能取成功 
   return OVERFLOW;
  if (!DeQueue_rear(&Q, &c))//取出队尾元素,同时检查是否能取成功
   return OVERFLOW;
  //队长不为零,取队头元素和队尾元素比较
  if (b != c) //如果检测出有一对队头与队尾字符不匹配,就证明这个字符串不是中心对称的 
  {
   printf("不是中心对称字符序列!\n");
   return FALSE;
  }
 }
 if (Q.rear == Q.front)//当从队头队尾删除字符的两个指针相遇时,说明他们之前的字符都成功匹配上了 
  printf("是中心对称字符序列!");
 return OK;
}
int main() {
 char a[100];//定义字符数组 
 printf("请输入要检验的字符序列,以#作为结束标志!\n");
 gets(a);//接收字符串 
 Match(a);//数组名做实参,把数组首元素的地址传递给形参 
 system("pause");
 return 0;
}

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值