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;
}