数据结构练习题

家人们,我来了,学习打卡

0a602bfeff134a4598eca837f1acb787.jpeg

 bf7b1a4d137f46f3bcba1217ca088f95.jpeg

废话不多说正文开始

今天来看栈和队列

 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 用来模拟顺序栈。请实现给出的isEmptyPushgetTopPop这四个函数。

裁判测试程序样例:

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

 

哦,坚持住了,我撤了家人们

  • 21
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值