数据结构和算法2(栈和队列)

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

栈的顺序存储结构

typedef struct
{
  ElemType *base;
  ElemType *top;
  int stackSize;
}sqStack;

base是指向栈底的指针,top是指向栈顶的指针,stackSize是指栈的当前可使用的最大容量。
创建一个栈

在这里插入图片描述
入栈:入栈又叫压栈,在栈顶进行,每次入栈,top指针就加1,直到栈满。
在这里插入图片描述
出栈
在栈顶取出数据,栈顶指针下移,当前容量减1在这里插入图片描述
另一种声明方法
在这里插入图片描述
清空一个栈
清空一个站就是将栈中的元素全部作废,但栈本身物理空间不改变(不是销毁)。

ClearStack(sqStack *s){
	s->top = s->base;
}

销毁一个栈
销毁是要释放掉该栈所占据的物理内存空间
在这里插入图片描述
计算栈的当前容量
也就是计算栈中元素的个数,只要返回s.top-s.base即可

int StackLen(sqStack s){
  return (s.top - s.base)//中间隔了几个元素,就相当于指针的差值再除以每个单元所占的内存,指针可相减,不可相加
}

二进制到八进制的转换
在这里插入图片描述

栈的链式存储结构

栈因为只是用栈顶来插入和删除,所以比较好的方法就是将栈顶放在单链表的头部,栈顶指针和单链表的头指针合二为一。在这里插入图片描述
在这里插入图片描述
进栈
在这里插入图片描述
出栈
在这里插入图片描述
逆波兰表达式
在这里插入图片描述
1.在这里插入图片描述
2.在这里插入图片描述
3.然后遇到乘法运算符,将9和-1弹出栈进行乘法运算,此时栈空,并且没有数据压栈,-9为最终结果

逆波兰计算器

在这里插入图片描述

int main(){
	sqStack s;
	char c;
	double d,e;
	char str[MAXBUFFER];
	int i = 0;
	InitStack(&s);
	printf("请按逆波兰表达式输入待计算数据,数据和运算符之间用空格隔开,以#作为结束标志");
	scanf("%c", &c);
	while(c != '#') {
		while(isdigit(c) || c=='.'){
			str[i++] = c;
			str[i] = '\0';
			if (i>=10){
				printf("出错,输入的单个数据过大\n");
				return -1;
			}
			scanf("%c",&c);
			if(c == ''){
				d = atof(str);//字符串转double
				push(&s,d);
				i = 0;
				break;
			}
		}
    	switch (c) {
    		case '+':
    			pop(&s, &e);
    			pop(&s,&d);
    			push(&s, d+e);
    			break;
    		case '-':
    			pop(&s, &e);
    			pop(&s,&d);
    			push(&s, d-e);
    			break;
    		case '*':
    			pop(&s, &e);
    			pop(&s,&d);
    			push(&s, d*e);
    			break;
    		case '/':
    			pop(&s, &e);
    			pop(&s,&d);
    			if (e != 0){
					push(&s, d/e);
				}else {
					printf("\n出错:除数为零\n");
					return -1;
				}
				break;	
    	}
    	scanf("%c", &c);
    }
    pop(&s,&d)
    printf("\n最终的计算结果为:%f\n", d)
    return 0;
}

中缀表达式转为后缀表达式

(1-2)*(4+5) ===>  1 2 - 4 5 + *

利用栈的记忆,符号都推入栈即可
以上可转化为:1+(2-3)*4+10/5

  1. 首先遇到第一个输入的是数字1,数字在后缀表达式中都是直接输出,接着是符号‘+’入栈在这里插入图片描述
  2. 在这里插入图片描述
  3. 在这里插入图片描述
  4. 紧接着是符号‘*’,直接入栈
  5. 在这里插入图片描述在这里插入图片描述
  6. 紧接着是数字10,输出,最后是符号‘/’,进栈
  7. 最后一个数字5,输出,所有输入处理完毕,但是栈里还有数据,所以将栈中符号依次出栈。
    在这里插入图片描述
    代码实现
int main(){	
	sqStack s;
	char c, e;
	InitStack(&s);
	printf("请输入中缀表达式,以#作为结束标志");
	scanf("%c",&c);

	while(c != '#'){
		if (c >= '0' && c <= '9'){
			printf("%c", c);
		} else if (')' == c){
			pop(&s, &e);
			while('(' != e){
				printf("%c", e);
				pop(&s, &e);
			}
		} else if('+' == c || '-' == c){
			if(!StackLen(s)){//若栈空,直接入栈
				push(&s, c);
			} else {
				do {
					pop(&s,&e);
					if('(' == e){
						push(&s,e)
					} else {
						printf("%c",e);
					}
				} while(StackLen(s) && '(' != e);
				push(&s, c);
			}
		} else if ('*' == c || '/'==c || '(' == c){
			push(&s, c);
		} else {
			printf("\n输入错误\n");
			return -1;
		}
		scanf("%c", &c);
	}
	while(StackLen(s)){
		pop(&s, &e);
		printf("%c", e);
	}
	return 0;
}

队列

在这里插入图片描述
队列的链式存储结构
对列既可以用链表实现,也可以用顺序表来实现。跟栈相反,栈一般用顺序表实现,而对列常用链表实现,简称为链对列。
在这里插入图片描述
在这里插入图片描述
创建一个空队列
在内存中创建一个头节点,然后队列的头指针和尾指针都指向它,此时即为空队列。
在这里插入图片描述
入队列操作
在这里插入图片描述
在这里插入图片描述
出队列操作
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
销毁一个队列
在这里插入图片描述
队列的顺序存储结构
假设队列有n个元素,则顺序存储的的队列需建立一个大于n的存储单元,并把队列的所有元素存储在数组的前n个单元,下标为0的一端是队头。
在这里插入图片描述
改进:我们不去限制队头一定要在下标为0的位置,那么出队列的操作也就不移动全体元素了。
在这里插入图片描述
上问题又叫假溢出,要解决假溢出的方法就是,如果后面满了,就再从头开始,也就是头尾相接的循环

循环队列
循环队列的容量是固定的,并且它的队头和队尾可随着元素出入队列而发生改变,这样的队列逻辑上就好像一个环形存储空间。
在这里插入图片描述
在这里插入图片描述
循环队列代码
定义一个循环队列

在这里插入图片描述
初始化
在这里插入图片描述
入队列
在这里插入图片描述
出队列
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值