链栈与循环队列的练习

链栈与循环队列的练习

这次实验分成三个部分,一共三个.cpp文件,其中第一个实验要求我用的是顺序栈,没看清要求,这个大家自行修改。

实验要求:
1、用堆栈(链栈)实现括号匹配算法,其中要求对所给出字符串中的{}、【】、()均可检测是否匹配。
2、设计算法实现计算后缀表达式求值(只限一位整数的加减乘除运算)
3、借助循环队列实现将堆栈中的给定值删除。

实验代码如下:
第一个实验要求代码:

#include
#include 
#define MAXSIZE 100

typedef struct {
	int *base;    //栈底指针
	int *top;     //栈顶指针
	int stacksize;//栈可用最大容量 
} SqStack;		  //定义栈元素的数据类型 

void InitStack(SqStack *s) {
	s->base = (int *)malloc(MAXSIZE*sizeof(int));//分配内存空间  100*sizeof(int)
	if (!s->base) {
		printf("分配失败\n");
	}
	s->top = s->base;		//设置栈底指针和栈顶指针,表示栈为空 
	s->stacksize = MAXSIZE;	//设置栈大小 
}

void push(SqStack *s, char x) {  //元素进栈
	if (s->top - s->base == s->stacksize) { 
		printf("栈满\n");		//栈满
	}
	*s->top++ = x;			//元素压入栈顶,栈顶指针加1 
}

char GetTop(SqStack *s)   //取栈栈顶元素
{
	if (s->top != s->base) {
		return *(s->top-1);		//返回栈顶元素的值,栈顶指针不变 
	}
}

char pop(SqStack *s) { 		 //元素出栈
	if (s->top == s->base) {
		return' ';
	}
	char e;
	e = *--s->top;			//栈顶指针减1,将栈顶元素赋值给e 
	return e;
}

int Matching() {
	SqStack ss;     //声明一个结构体 
	SqStack *s = &ss;  //指向结构体的指针
	InitStack(s);
	int flag = 1;
	printf("请输入一串需要匹配的符号(以#结尾):\n");
	char ch = getchar();
	while(ch != '#' && flag) {
		switch(ch) {
			case '[':
			case '(':
			case '{': 
				push(s,ch);
				break;
			case ')':
				if(!(s->top == s->base) && GetTop(s) == '(')
					pop(s);
				else flag = 0;
				break;
			case']':
				if (!(s->top == s->base) && GetTop(s) == '[')
					pop(s);
				else flag = 0;
				break;
			case '}':
				if (!(s->top == s->base) && GetTop(s) == '{')
					pop(s);
				else flag = 0;
				break;
		}
		ch = getchar();
	}
	if ((s->top == s->base) && flag) return 1;
	else return 0;
}

int main() {
	
	Matching();
	if(Matching() == 1) {
		printf("匹配成功!\n");
	}
	else printf("匹配失败!\n");
	return 0;
}

运行结果如下:
链栈与循环队列的练习_第1张图片第一个实验第一次输入不要当真,随便输入,第二次才是真正的开始,哈哈!

第二个实验要求代码:

#include 
#include 
#define Maxlen 88

typedef struct {
	char data [Maxlen];
	int top;

} opstack;

typedef struct {
	float data[Maxlen];
	int top;
} stack;

void trans (char str[],char exp[]) { //求后缀表达式
	opstack op;
	char ch;
	int i=0, t=0;
	op.top=- 1;
	ch = str[i];
	i++ ;
	while(ch !='\0' ) {
		switch (ch) {
			case '(' :

				op.top++ ;
				op.data[op.top] =ch;
				break;
			case ')' :
				while (op.data[op.top]!='(') {
					exp[t]=op.data[op.top];
					op.top-- ;
					t++;
				}
				op.top-- ;
				break;
			case '+' :
			case '-' :
				while(op.top != -1 && op.data[op.top]!='(') {
					exp[t]=op.data[op.top];
					op.top-- ;
					t++;
				}
				op.top++;
				op.data[op.top]=ch;
				break;
			case '*' :
			case '/' :
				while(op.top=='/' || op.top == '*') {
					exp[t]=op.data[op.top];
					op.top--;
					t++;
				}
				op.top++;
				op.data[op.top]=ch;
				break;

			case ' ':
				break;//输入为空格,则跳过
			default:
				while(ch>='0' && ch <= '9' ) {
					exp[t]=ch;
					t++;
					ch=str[i];
					i++;
				}
				i--;
				exp[t]=' ';
				t++;
		}
		ch=str[i];
		i++;
	}
	while(op.top!=-1) {
		exp[t]=op.data[op.top];
		t++;
		op.top--;
	}
	exp[t]='\0';
}
float compvalue (char exp[]) {		//后缀表达式求值
	stack st;
	float d;
	char ch;
	int t=0;
	st.top = -1;
	ch=exp[t];
	t++;
	while(ch!='\0') {
		switch (ch) {
			case '+' :
				st.data[st.top-1]=st.data[st.top-1]+st.data[st.top];
				st.top-- ;
				break;

			case '-' :
				st.data[st.top-1]=st.data[st.top-1]-st.data[st. top];
				st.top--;
				break;
			case '*' :
				st.data[st.top-1]=st.data[st.top-1]*st.data[st.top];
				st.top-- ;
				break;
			case '/':
				if (st.data[st.top]!=0) {
					st.data[st.top-1]=st.data[st.top-1]/st.data[st.top];
					st.top--;
				} else
					printf("\n\t表达式中有除数为零,本次计算无效!\n ");
				break;
			default:
				d=0;
				while(ch>='0' && ch<='9' ) {
					d = 10*d + ch -'0';
					ch=exp[t];
					t++;
				}
				st.top++;
				st.data[st.top]=d;
		}
		ch=exp[t];
		t++;
	}
	return st.data[st.top];
}
int main() {
	char str [Maxlen], exps [Maxlen];
	printf("\n请输入一个算术表达式: ");
	printf("\n提示:操作数的范围是“0-9”,运算符只含+,-, *, /和括号,中间不可以有空格\n");
	gets(str) ;
    printf("\n原算术表达式为: %s\n" ,str) ;
	trans(str, exps) ;
    printf("\n其后缀表达式为: %s\n" , exps);
	printf("\n其运算的结果为: %g\n\n", compvalue(exps));
}

运行结果如下:
链栈与循环队列的练习_第2张图片第三个实验要求代码:

#include
#include
#define ERROR 0
#define MAXQSIZE 100
typedef int Status;
typedef int QElemType;
typedef struct {
	int *base;
	int front;
	int rear;
} SqQueue;

Status InitQueue(SqQueue &Q) {
	Q.base=(QElemType*)malloc(MAXQSIZE*sizeof(QElemType));
	if(!Q.base)  return ERROR;
	Q.front=Q.rear=0;
	return 0;
}

Status QueueLength(SqQueue &Q) {
	int length;
	length=(Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
	return length;
}

Status EnQueue(SqQueue &Q,QElemType e) {
	if((Q.rear+1)%MAXQSIZE==Q.front) return ERROR;
	Q.base[(Q.rear)]=e;
	Q.rear=(Q.rear+1)%MAXQSIZE;
	return 0;
}

Status DeQueue(SqQueue &Q) {
	int e,test;
	if(Q.front==Q.rear) return ERROR;
	test=Q.front;
	e=Q.base[Q.front];
	Q.front=(Q.front+1) % MAXQSIZE;
	return e;
}

int JudgeEmpty(SqQueue &Q) {
	/*if((Q.rear+1)%MAXQSIZE==Q.front) printf("The queue is full\n");
	else  if(Q.rear==Q.front) printf("The queue is Empty\n");
	else printf("The queue is not empty!\n");*/
	if(Q.front==Q.rear) 
	return 1;
	return 0;
}

void DstoryQueue(SqQueue &Q) { //销毁
	while ( Q.front!= Q.rear) {
		free(&Q.base[Q.front]);
		Q.front=(Q.front+1)%MAXQSIZE;
	}
}

void  ClearQueue(SqQueue &Q) { //清空
	int i=Q.front;
	while (i != Q.rear) {
		i=0;
		i++;
	}
	Q.front=Q.rear=0;
}

Status GetHead(SqQueue &Q) { //取首元素
	QElemType e;
	if(Q.front==Q.rear)
		return ERROR;
	return e=Q.base[Q.front];
}

void QueueTraver(SqQueue &Q) {
	int i=Q.front;
	while (i!=Q.rear) {
		printf("%5d",Q.base[i]);
		i++;
	}
}
void CreatQueue(SqQueue &Q) {
	int n;
	printf("请输入循环队列的长度:");
	scanf("%d",&n);
	for (int i = 1; i <=n; i++) {
		printf("第%d个元素为:",i);
		scanf("%d",&Q.base[Q.rear]);
		Q.rear=(Q.rear+1)%MAXQSIZE;
	}
}

int main()
{   int a;
    SqQueue Q;
	InitQueue(Q);//初始化调试
	printf("准备测试队列操作....\n\n");
	CreatQueue(Q);//创建循环队列
	printf("\n\n");
	printf("队列长度为:%d", QueueLength(Q));//求队长
	printf("\n\n");
	if(JudgeEmpty(Q) == 0)
	printf("队列不空!");
	else printf("队列为空!");
	printf("\n\n队列中的元素为:");
	QueueTraver(Q);//遍历调试
	printf("\n\n");
	printf("首元素为:%d", GetHead(Q));//取首元素
	printf("\n\n");printf("删除队头元素:%d", DeQueue(Q));//删除
	printf("\n\n剩下元素为:");
	QueueTraver(Q);//遍历调试
/*	printf("\n\n");
	printf("请输入要添加的元素:");
	scanf("%d",&a);
	printf("\n\n你要添加的元素为:%d", EnQueue(Q,a));
	printf("\n\n剩下元素为:");
	QueueTraver(Q);//遍历调试
	ClearQueue(Q);
	DstoryQueue(Q);
    return 0;*/
}

因为没有理解老师的意思,所以跟实验要求不是很对应,但是运气好,代码通过了,哈哈哈!

运行结果如下:
链栈与循环队列的练习_第3张图片虽然代码有很多小bug,但整体思路还是有的,通过这些实验,让我对栈和队列的使用更加熟悉了!

你可能感兴趣的:(链栈与循环队列的练习)