数据结构——栈与队列

本文详细讲解了中缀表达式转后缀表达式、括号匹配规则以及用栈实现队列和约瑟夫环问题的解决方法,涉及基础IT技术和数据结构的运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

 1. 中缀表达式转换为后缀表达式

 2. 括号匹配问题

3. 栈实现队列

4. 约瑟夫环


 1. 中缀表达式转换为后缀表达式

【问题描述】
 输入一个中缀表达式,表达式中有+、-、*、/四种运算以及(、),表达式中的其他符号为大写的字母。实现一个算法,得到相应的后缀表达式。

【输入形式】
 一个式子的中缀表达式,以#结束

【输出形式】
 相应的后缀表达式 

【样例输入】

 A*(B-C)/D+E#

【样例输出】

 ABC-*D/E+

【评分标准】
 请大家在程序中写出必要的注释,如果程序没有必要的注释,将酌情扣分


#include<stdio.h>
#include<string.h>

#define MAX_SIZE 100
typedef struct {
    char data[MAX_SIZE];
    int top;
}Stack;

void init(Stack *stack){
    stack->top=-1;
}

int isEmpty(Stack *stack){
    return stack->top==-1;
}

int isFull(Stack *stack){
    return stack->top==MAX_SIZE-1;
}

void push(Stack *stack,char c){
    if(isFull(stack)){
        printf("Stack overflow\n");
        return;
    }
    stack->data[++stack->top]=c;
}

char pop(Stack *stack){
    if(isEmpty(stack)){
        printf("Stack underflow\n");
        return '\0';
    }
    return stack->data[stack->top--];
}

int getPriority(char c){
    if(c=='+'||c=='-'){
        return 1;
    }
    else if(c=='*'||c=='/'){
        return 2;
    }
    else{
        return 0;
    }
}

void infixToPostfix(char *infix, char *postfix){
    Stack s;
    init(&s);
    int i=0, j=0;
    while(infix[i]!='#'){
        if(infix[i]>='A'&&infix[i]<='Z'){
            postfix[j++]=infix[i];
        }
        else if(infix[i]=='('){
            push(&s, infix[i]);
        }
        else if(infix[i]==')'){
            while(!isEmpty(&s) && s.data[s.top]!='('){
                postfix[j++]=pop(&s);
            }
            if(!isEmpty(&s) && s.data[s.top]=='('){
                pop(&s);
            }
        }
        else{
            while(!isEmpty(&s) && getPriority(infix[i])<=getPriority(s.data[s.top])){
                postfix[j++]=pop(&s);
            }
            push(&s, infix[i]);
        }
        i++;
    }
    while(!isEmpty(&s)){
        postfix[j++]=pop(&s);
    }
    postfix[j]='\0';
}

int main(){
    char infix[MAX_SIZE];
    scanf("%s", infix);
    char postfix[MAX_SIZE];
    infixToPostfix(infix, postfix);
    printf("%s\n", postfix);
    return 0;
}

 2. 括号匹配问题

【问题描述】

假设一算术表达式中包括三种括号:圆括号"("和")",方括号"["和"]",花括号"{"和"}",且三种括号可按意 次序嵌套使用,试编写程序判定输入的表达式所含的括号是否正确配对出现(已知表达式已存入数据元素为字符的顺序表中)。若匹配,则返回1,否则返回0。
【输入形式】

含括号的算数表达式
【输出形式】

1或者0

【样例输入】

3+(44*[5-{6*[7*(45-10)]}])

【样例输出】

1

【样例说明】

判断括号是否匹配涉及两方面,括号个数和出现次序的判定。
【评分标准】

#include <stdio.h>
#include <string.h>
 
#define MAX_SIZE 100
 
typedef struct {
    char data[MAX_SIZE];
    int top;
} Stack;
 
void init(Stack *stack) {
    stack->top = -1;
}
 
int isEmpty(Stack *stack) {
    return stack->top == -1;
}
 
int isFull(Stack *stack) {
    return stack->top == MAX_SIZE - 1;
}
 
void push(Stack *stack, char c) {
    if (isFull(stack)) {
        printf("Stack overflow\n");
        return;
    }
    stack->data[++stack->top] = c;
}
 
char pop(Stack *stack) {
    if (isEmpty(stack)) {
        printf("Stack underflow\n");
        return '\0';
    }
    return stack->data[stack->top--];
}
 
int isMatching(char left, char right) {
    if (left == '(' && right == ')') {
        return 1;
    } else if (left == '[' && right == ']') {
        return 1;
    } else if (left == '{' && right == '}') {
        return 1;
    } else {
        return 0;
    }
}
 
int isParenthesesMatching(char *expression) {
    Stack stack;
    init(&stack);
    int i;
    int length = strlen(expression);
    for ( i = 0; i < length; i++) {
        char c = expression[i];
        if (c == '(' || c == '[' || c == '{') {
            push(&stack, c);
        } else if (c == ')' || c == ']' || c == '}') {
            if (isEmpty(&stack)) {
                return 0;
            }
            char top = pop(&stack);
            if (!isMatching(top, c)) {
                return 0;
            }
        }
    }
    return isEmpty(&stack);
}
 
int main() {
    char expression[MAX_SIZE];
    fgets(expression, MAX_SIZE, stdin);
    int result = isParenthesesMatching(expression);
    printf("%d\n", result);
    return 0;
}

3. 栈实现队列

【问题描述】

请使用栈类实现队列的类。

【输入形式】

第一行一个整数n,

接下来n行,每行一个整数,依次表示已经在队列中的数。

接下来一行,一个整数m。

接下来m行,有两种情况:1. 一个整数,请将其入列。2. 字符串"D",表示出列操作。

【输出形式】

若干行,每行一个出列的输出。

【样例输入】

3
1
2
3
2
4
D

【样例输出】

1

【样例说明】

队列中原来有1,2,3三个数,第一个操作使4入列,第二个操作出列,弹出队头的1
【评分标准】

通过所有数据

#include <stdio.h>
#include <string.h>

#define MAX_SIZE 100

typedef struct {
    int data[MAX_SIZE];
    int top;
} Stack;

void init(Stack *stack) {
    stack->top = -1;
}

int isEmpty(Stack *stack) {
    return stack->top == -1;
}

int isFull(Stack *stack) {
    return stack->top == MAX_SIZE - 1;
}

void push(Stack *stack, int num) {
    if (isFull(stack)) {
        printf("Stack overflow\n");
        return;
    }
    stack->data[++stack->top] = num;
}

int pop(Stack *stack) {
    if (isEmpty(stack)) {
        printf("Stack underflow\n");
        return 0;
    }
    return stack->data[stack->top--];
}

int main() {
    int n, m;
    scanf("%d", &n);
    Stack s1, s2;
    init(&s1);
    init(&s2);
    int i;
    for (i = 0; i < n; i++) {
        int num;
        scanf("%d", &num);
        push(&s1, num);
    }
    scanf("%d", &m);
    for (i = 0; i < m; i++) {
        char temp_str[2];
        scanf("%s", temp_str);
        if (strcmp(temp_str, "D") == 0) {
            if (isEmpty(&s2)) {
                while (!isEmpty(&s1)) {
                    int num = pop(&s1);
                    push(&s2, num);
                }
            }
            int result = pop(&s2);
            printf("%d\n", result);
            n--;
        } else {
            int num = atoi(temp_str);
            push(&s1, num);
            n++;
        }
    }
    return 0;
}

4. 约瑟夫环

【问题描述】

n个人围成一个圈,按顺时针方向一次编号1、2、3、……、n,从第一个人开始顺时针方向依次报数1、2、3、……,报数m的人被淘汰,然后下一个人再从1开始报数,一直重复该过程。由于人数是有限的,因此最后一定只会剩下一个人,求这个人的编号。

【输入形式】

第一行,一个整数n,表示约瑟夫环的总人数。

第二行,一个整数m,表示报到m的人被淘汰。

【输出形式】

 一行,一个整数,约瑟夫环最终剩下的人的编号。

【样例输入】

5
2

【样例输出】

3

【样例说明】

5个人围成一圈,编号1,2,3,4,5;

第一轮,2号淘汰,剩下1,3,4,5;

第二轮,从3开始报数,4号淘汰,剩下1,3,5;

第三轮,从5开始报数,1号淘汰,剩下3,5;

第四轮,从3开始报数,5号淘汰,剩下3。
【评分标准】

通过所有数据

#include <stdio.h>
#include <stdlib.h>
 
typedef struct Node {
    int data;
    struct Node* next;
} Node,*LinkList;
 
LinkList createNode(int data) {
    LinkList newNode = (LinkList)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}
 
void appendNode(LinkList* head, int data) {
    LinkList newNode = createNode(data);
    if (*head == NULL) {
        *head = newNode;
        newNode->next = *head;
    } else {
        LinkList temp = *head;
        while (temp->next != *head) {
            temp = temp->next;
        }
        temp->next = newNode;
        newNode->next = *head;
    }
}
 
void deleteNode(LinkList* head, int m) {
    if (*head == NULL) {
        return;
    }
    LinkList current = *head;
    LinkList prev = NULL;
    while (current->next != *head) {
        prev = current;
        current = current->next;
    }
    if (current == *head && current->next == *head) {
        *head = NULL;
        free(current);
        return;
    }
        int i;
        for ( i = 1; i <=m; i++) {
            prev = current;
            current = current->next;
        }
        prev->next = current->next;
        free(current);
        *head = prev->next;
}
 
int josephus(int n, int m) {
    LinkList head = NULL;
    int i;
    for (i = 1; i <= n; i++) {
        appendNode(&head, i);
    }
    while ( head!=head->next) {
        deleteNode(&head, m);
    }
    return head->data;
}
 
int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    int result = josephus(n, m);
    printf("%d\n", result);
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值