家人们,我来了,学习打卡
废话不多说正文开始
今天来看栈和队列
6.另类堆栈
在栈的顺序存储实现中,另有一种方法是将Top定义为栈顶的上一个位置。请编写程序实现这种定义下堆栈的入栈、出栈操作。如何判断堆栈为空或者满?
函数接口定义:
bool Push( Stack S, ElementType X );
ElementType Pop( Stack S );
其中Stack结构定义如下:
typedef int Position;
typedef struct SNode *PtrToSNode;
struct SNode {
ElementType *Data; /* 存储元素的数组 */
Position Top; /* 栈顶指针 */
int MaxSize; /* 堆栈最大容量 */
};
typedef PtrToSNode Stack;
注意:如果堆栈已满,Push函数必须输出“Stack Full”并且返回false;如果队列是空的,则Pop函数必须输出“Stack Empty”,并且返回ERROR。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
#define ERROR -1
typedef int ElementType;
typedef enum { push, pop, end } Operation;
typedef enum { false, true } bool;
typedef int Position;
typedef struct SNode *PtrToSNode;
struct SNode {
ElementType *Data; /* 存储元素的数组 */
Position Top; /* 栈顶指针 */
int MaxSize; /* 堆栈最大容量 */
};
typedef PtrToSNode Stack;
Stack CreateStack( int MaxSize )
{
Stack S = (Stack)malloc(sizeof(struct SNode));
S->Data = (ElementType *)malloc(MaxSize * sizeof(ElementType));
S->Top = 0;
S->MaxSize = MaxSize;
return S;
}
bool Push( Stack S, ElementType X );
ElementType Pop( Stack S );
Operation GetOp(); /* 裁判实现,细节不表 */
void PrintStack( Stack S ); /* 裁判实现,细节不表 */
int main()
{
ElementType X;
Stack S;
int N, done = 0;
scanf("%d", &N);
S = CreateStack(N);
while ( !done ) {
switch( GetOp() ) {
case push:
scanf("%d", &X);
Push(S, X);
break;
case pop:
X = Pop(S);
if ( X!=ERROR ) printf("%d is out\n", X);
break;
case end:
PrintStack(S);
done = 1;
break;
}
}
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
4
Pop
Push 5
Push 4
Push 3
Pop
Pop
Push 2
Push 1
Push 0
Push 10
End
输出样例:
Stack Empty
3 is out
4 is out
Stack Full
0 1 2 5
提交答案
bool Push(Stack S, ElementType X ) {
if(S->Top==S->MaxSize)
{
printf("Stack Full\n");
return false;
}
S->Data[S->Top]=X;
S->Top+=1;
}
ElementType Pop( Stack S ) {
ElementType i;
if(S->Top==0)
{
printf("Stack Empty\n");
return ERROR;
}
i=S->Data[--S->Top];
return i;
}
7.在一个数组中实现两个堆栈
本题要求在一个数组中实现两个堆栈。
函数接口定义:
Stack CreateStack( int MaxSize );
bool Push( Stack S, ElementType X, int Tag );
ElementType Pop( Stack S, int Tag );
其中Tag
是堆栈编号,取1或2;MaxSize
堆栈数组的规模;Stack
结构定义如下:
typedef int Position;
struct SNode {
ElementType *Data;
Position Top1, Top2;
int MaxSize;
};
typedef struct SNode *Stack;
注意:如果堆栈已满,Push
函数必须输出“Stack Full”并且返回false;如果某堆栈是空的,则Pop
函数必须输出“Stack Tag Empty”(其中Tag是该堆栈的编号),并且返回ERROR。
裁判测试程序样例:
#include <stdio.h>
#include <stdlib.h>
#define ERROR 1e8
typedef int ElementType;
typedef enum { push, pop, end } Operation;
typedef enum { false, true } bool;
typedef int Position;
struct SNode {
ElementType *Data;
Position Top1, Top2;
int MaxSize;
};
typedef struct SNode *Stack;
Stack CreateStack( int MaxSize );
bool Push( Stack S, ElementType X, int Tag );
ElementType Pop( Stack S, int Tag );
Operation GetOp(); /* details omitted */
void PrintStack( Stack S, int Tag ); /* details omitted */
int main()
{
int N, Tag, X;
Stack S;
int done = 0;
scanf("%d", &N);
S = CreateStack(N);
while ( !done ) {
switch( GetOp() ) {
case push:
scanf("%d %d", &Tag, &X);
if (!Push(S, X, Tag)) printf("Stack %d is Full!\n", Tag);
break;
case pop:
scanf("%d", &Tag);
X = Pop(S, Tag);
if ( X==ERROR ) printf("Stack %d is Empty!\n", Tag);
break;
case end:
PrintStack(S, 1);
PrintStack(S, 2);
done = 1;
break;
}
}
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
5
Push 1 1
Pop 2
Push 2 11
Push 1 2
Push 2 12
Pop 1
Push 2 13
Push 2 14
Push 1 3
Pop 2
End
输出样例:
Stack 2 Empty
Stack 2 is Empty!
Stack Full
Stack 1 is Full!
Pop from Stack 1: 1
Pop from Stack 2: 13 12 11
提交答案
Stack CreateStack( int MaxSize ){
Stack a=(struct SNode *)malloc(sizeof(struct SNode));//先为栈分配一个空间
a->Data=(int*)malloc(sizeof(ElementType)*MaxSize);//为栈分配一个Macsize大小的数组空间存放值
a->Top1 = -1;
a->Top2 = MaxSize;
a->MaxSize = MaxSize;
return a;
}
bool Push( Stack S, ElementType X, int Tag ){
int a;
if(S->Top1+1!=S->Top2){
if(Tag==1){
a=S->Top1;
S->Top1++;
S->Data[a]=X;
}
else if(Tag==2){
a=S->Top2;
S->Top2--;
S->Data[a]=X;
}
return true;
}
else{
printf("Stack Full\n");
return false;
}
}
ElementType Pop( Stack S, int Tag ){
int a;
if(Tag==1){
if(S->Top1!=-1){
a=S->Top1-1;
S->Top1--;
return S->Data[a];
}
else{
printf("Stack 1 Empty\n");
return ERROR;
}
}
else{
if(S->Top2!=S->MaxSize){
a=S->Top2+1;
S->Top2++;
return S->Data[a];
}
else{
printf("Stack 2 Empty\n");
return ERROR;
}
}
}
60多行代码
8.十进制转二进制(顺序栈设计和应用)
设计一个顺序栈,并利用该顺序栈将给定的十进制整整数转换为二进制并输出。
函数接口定义:
#define MaxSize 100 /* 栈最大容量 */
int top; /* 栈顶指针 */
int mystack[MaxSize]; /* 顺序栈 */
/*判栈是否为空,空返回true,非空返回false */
bool isEmpty();
/* 元素x入栈 */
void Push(int x);
/* 取栈顶元素 */
int getTop();
/* 删除栈顶元素 */
void Pop();
其中 MaxSize
和 top
分别为栈的最大容量和栈顶指针。数组mystack
用来模拟顺序栈。请实现给出的isEmpty
、Push
、getTop
和Pop
这四个函数。
裁判测试程序样例:
#include <bits/stdc++.h>
using namespace std;
#define MaxSize 100 /* 栈最大容量 */
int top; /* 栈顶指针 */
int mystack[MaxSize]; /* 顺序栈 */
/*判栈是否为空,空返回true,非空返回false */
bool isEmpty();
/* 元素x入栈 */
void Push(int x);
/* 取栈顶元素 */
int getTop();
/* 删除栈顶元素 */
void Pop();
/* 十进制正整数转换为二进制 */
void dec2bin(int x) {
top = -1; /* 初始化栈顶指针 */
while (x) {
Push(x % 2);
x >>= 1;
}
while (!isEmpty()) {
int t = getTop();
Pop();
printf("%d", t);
}
printf("\n");
}
int main(int argc, char const *argv[])
{
int n;
while (scanf("%d", &n) != EOF) {
dec2bin(n);
}
return 0;
}
/* 请在这里填写答案 */
输入样例:
10
输出样例:
1010
提交答案
bool isEmpty(){
if(top==-1)
return true;
else
return false;
}
void Push(int x){
if(top!=MaxSize){
top++;
mystack[top]=x;
}
}
int getTop(){
return mystack[top];
}
void Pop(){
top=top-1;
}
9.汉诺塔的非递归实现
借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c),即将N个盘子从起始柱(标记为“a”)通过借助柱(标记为“b”)移动到目标柱(标记为“c”),并保证每个移动符合汉诺塔问题的要求。
输入格式:
输入为一个正整数N,即起始柱上的盘数。
输出格式:
每个操作(移动)占一行,按柱1 -> 柱2
的格式输出。
输入样例:
3
输出样例:
a -> c
a -> b
c -> b
a -> c
b -> a
b -> c
a -> c
提交答案
#include<stdio.h>
void Hanoi(int n,int a,int b,int c)
{
if(1==n)
{
printf("%c -> %c\n",a,c);
}
else
{
Hanoi(n-1,a,c,b);
Hanoi( 1 ,a,b,c);
Hanoi(n-1,b,a,c);
}
}
printf("%c -> %c\n",a,c);
int main()
{
int N;
scanf("%d",&N);
Hanoi(N,'a','b','c');
return 0;
}
10.后缀式求值
我们人类习惯于书写“中缀式”,如 3 + 5 * 2
,其值为13
。 (p.s. 为什么人类习惯中缀式呢?是因为中缀式比后缀式好用么?)
而计算机更加习惯“后缀式”(也叫“逆波兰式”,Reverse Polish Notation)。上述中缀式对应的后缀式是: 3 5 2 * +
现在,请对输入的后缀式进行求值。
输入格式:
在一行中输入一个后缀式,运算数
和运算符
之间用空格分隔,运算数长度不超过6
位,运算符仅有+ - * /
四种。
输出格式:
在一行中输出后缀式的值,保留一位小数。
输入样例:
3 5.4 2.2 * +
输出样例:
14.9
提交答案
#include <stdio.h>
int main(){
char str[10];
double st[100];
int i=0;
while(~scanf("%s", str)){
if(str[1] == '\0' && (str[0] == '+'||str[0] == '-'||str[0] == '*'||str[0] == '/')){
double num1, num2, res;
num1 = st[--i];
num2 = st[--i];
switch(str[0]){
case '+': res = num2 + num1; st[i++]=res; break;
case '-': res = num2 - num1; st[i++]=res; break;
case '*': res = num2 * num1; st[i++]=res; break;
case '/': res = num2 / num1; st[i++]=res; break;
}
}else{
double number;
sscanf(str, "%lf", &number);
st[i++]=number;
}
}
printf("%.1lf", st[0]);
return 0;
}
11.队列的实现及基本操作
给定一个初始为空的队列和一系列入队、出队操作,请编写程序输出每次出队的元素。队列的元素值均为整数。
输入格式:
输入第1行为1个正整数n,表示操作个数;接下来n行,每行表示一个操作,格式为1 d或0。1 d表示将整数d入队,0表示出队。n不超过20000。
输出格式:
按顺序输出每次出队的元素,每个元素一行。若某出队操作不合法(如在队列空时出队),则对该操作输出invalid。
输入样例:
7
1 1
1 2
0
0
0
1 3
0
输出样例:
1
2
invalid
3
提交答案
#include <stdio.h>
int main()
{
int n;
scanf("%d",&n);
int a[10000];
int i,end;
int kaishi,xh,caozuo;
end=0;
kaishi=0;
for (i=1;i<=n;i++){
scanf("%d",&caozuo);
if(caozuo==1){
scanf("%d",&xh);
a[end]=xh;
end++;
}
else {
if(kaishi==end){
printf("invalid\n");
}
else {
printf("%d\n",a[kaishi]);
kaishi++;
}
}
}
return 0;
}