考研数据结构栈和队列

栈和队列

题目1

回文是指正读反读均相同的字符序列,如“abba”和“abdba”均是回文,但“good”不是回文。试写一个算法判断给定字符序列是否是回文(提示:将一半字符入栈)

【算法思想】

  1. 初始化一个空栈。
  2. 将字符串前半部分的字符依次入栈。
  3. 确定后半部分的起始位置,若字符串长度为奇数,则跳过中间字符。
  4. 从后半部分的起始位置开始,依次将字符与栈顶字符比较:
    • 如果所有字符都匹配,则字符串是回文;
    • 如果有任意一个字符不匹配,则字符串不是回文。
  5. 输出判断结果。
// 判断字符串是否是回文
int isPalindrome(const char *str) {
    int len = strlen(str);
    Stack stack;
    initStack(&stack);
    
    // 将前半部分字符入栈
    for (int i = 0; i < len / 2; i++) {
        push(&stack, str[i]);
    }
    
    // 如果字符串长度为奇数,跳过中间字符
    int startIndex = (len % 2 == 0) ? len / 2 : len / 2 + 1;
    
    // 比较后半部分字符与栈顶字符
    for (int i = startIndex; i < len; i++) {
        char topChar = pop(&stack);
        if (topChar != str[i]) {
            return 0; // 不是回文
        }
    }
    
    return 1; // 是回文
}

题目2

假设以数组 Q[m] 存放循环队列的元素,同时设置一个标志域名 tag,以 tag == 0 和 tag == 1 来区别头指针(front)和队尾指针(rear)相等时,队列状态为“空”还是“满”。试编写与此结构相应的插入(EnQueue)和删除(DeQueue)算法。

算法思想: 在循环队列中,增设一个 tag 类型的整型变量,进队时置 tag 为 1,出队时置 tag 为 0(因为入队操作可能导致队满,只有出队操作可能会导致队空)。队列 Q 初始化时,置 tag == 0,front == rear == 0。这样队列的 4 要素如下:

队空条件:Q.front == Q.rear && Q.tag == 0
队满条件:Q.front == Q.rear && Q.tag == 1
进队操作:Q.data[Q.rear] = x; Q.rear = (Q.rear + 1) % MaxSize; Q.tag = 1;
出队操作:x = Q.data[Q.front]; Q.front = (Q.front + 1) % MaxSize; Q.tag = 0;
// 进队操作
int EnQueue(Queue *Q, int x) {
    if (IsFull(*Q)) {
        printf("Queue is full!\n");
        return 0;
    }
    Q->data[Q->rear] = x;
    Q->rear = (Q->rear + 1) % MaxSize;
    Q->tag = 1;
    return 1;
}

// 出队操作
int DeQueue(Queue *Q, int *x) {
    if (IsEmpty(*Q)) {
        printf("Queue is empty!\n");
        return 0;
    }
    *x = Q->data[Q->front];
    Q->front = (Q->front + 1) % MaxSize;
    Q->tag = 0;
    return 1;
}

题目3

设计一个算法判断输入的表达式中括号是否配对(假设只含有左右圆括号)

算法思想

判断一个表达式中的括号是否配对是一个典型的栈应用问题。栈是一种后进先出的数据结构,非常适合处理这种配对问题。算法思想如下:

  1. 创建一个空栈。

  2. 遍历输入的表达式:

    • 如果遇到左括号 ‘(’,将其压入栈中。

    • 如果遇到右括号 ‘)’

      ,检查栈是否为空:

      • 如果栈为空,说明没有相应的左括号与之配对,表达式不配对,返回 false。
      • 如果栈不为空,从栈顶弹出一个左括号与之配对。
  3. 遍历结束后,检查栈是否为空:

    • 如果栈为空,说明所有的左括号都有相应的右括号配对,返回 true。
    • 如果栈不为空,说明有多余的左括号没有配对,返回 false。
// 检查表达式中的括号是否配对
bool areParenthesesBalanced(char* expr) {
    int length = 0;
    while (expr[length] != '\0') {
        length++;
    }

    Stack* stack = createStack(length);

    for (int i = 0; i < length; i++) {
        if (expr[i] == '(') {
            push(stack, expr[i]);
        } else if (expr[i] == ')') {
            if (isEmpty(stack)) {
                return false;  // 栈为空,没有与之配对的左括号
            }
            pop(stack);
        }
    }

    bool balanced = isEmpty(stack);
    free(stack->array);
    free(stack);

    return balanced;
}

题目4

假设表达式中允许包含三种括号:圆括号,方括号,大括号。试着编写一个算法判断表达式中的括号是否正确匹配

为了处理包含三种括号(圆括号、方括号、大括号)的表达式配对问题,可以对每种括号类型分别进行处理。总体的算法思想与之前的类似,但需要进行更复杂的匹配检查:

  1. 创建一个空栈。

  2. 遍历输入的表达式:

    • 如果遇到左括号'(', '[', '{',将其压入栈中。

    • 如果遇到右括号')', ']', '}'

      检查栈是否为空:

      • 如果栈为空,说明没有相应的左括号与之配对,表达式不配对,返回 false。
      • 如果栈不为空,从栈顶弹出一个左括号并检查是否与当前右括号配对。如果不匹配,返回 false。
  3. 遍历结束后,检查栈是否为空:

    • 如果栈为空,说明所有的左括号都有相应的右括号配对,返回 true。
    • 如果栈不为空,说明有多余的左括号没有配对,返回 false。
// 检查括号是否匹配
bool isMatchingPair(char character1, char character2) {
    return (character1 == '(' && character2 == ')') ||
           (character1 == '[' && character2 == ']') ||
           (character1 == '{' && character2 == '}');
}

// 检查表达式中的括号是否配对
bool areParenthesesBalanced(char* expr) {
    int length = 0;
    while (expr[length] != '\0') {
        length++;
    }

    Stack* stack = createStack(length);

    for (int i = 0; i < length; i++) {
        if (expr[i] == '(' || expr[i] == '[' || expr[i] == '{') {
            push(stack, expr[i]);
        } else if (expr[i] == ')' || expr[i] == ']' || expr[i] == '}') {
            if (isEmpty(stack)) {
                return false;  // 栈为空,没有与之配对的左括号
            } else if (!isMatchingPair(pop(stack), expr[i])) {
                return false;  // 栈顶左括号与当前右括号不匹配
            }
        }
    }

    bool balanced = isEmpty(stack);
    free(stack->array);
    free(stack);

    return balanced;
}

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心如止水Long

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值