初试811-数据结构(C语言)

第三章:堆栈和队列

Q&A:

1、阐述栈和队列的特点,并说明它们的作用

  • 栈是一种遵循先入后出原则的数据结构
     
  • 队列是一种遵循先入先出原则的数据结构

2、是分别写出判队列为空和队列为满的条件 

  • 判断队列为空的条件:front==rear
  • 判断队列为满的条件:(rear+1) %Max==front

3、什么是递归、递归算法?比较递归和非递归算法的优缺点 

递归(recursion)是数学概念,也是一种有用的程序设计方法,通过函数调用自身来解决问题。它主要包含两个阶段。

  • :程序不断深入地调用自身,通常传入更小或更简化的参数,直到达到“终止条件”。
  • :触发“终止条件”后,程序从最深层的递归函数开始逐层返回,汇聚每一层的结果。

而从实现的角度看,递归算法代码主要包含三个要素。

  • 终止条件:用于决定什么时候由“递”转“归”。
  • 递归调用:对应“递”,函数调用自身,通常输入更小或更简化的参数。
  • 返回结果:对应“归”,将当前递归层级的结果返回至上一层。

递归调用优缺点:

  • 优点:程序非常简洁清晰,且易于分析
  • 缺点:费时间(频繁的进栈出栈,甚至重复计算)、费空间(系统实现递归需要一个系统栈,当一个函数被调用时,系统创建一个工作记录📝,称为栈帧,并将其置于栈顶) 

4、利用栈可以检查表达式中括号是否配对,是编写算法实现之 

bool check(char str[])
{
    stack s;
    int i =0;     //遍历表达式
    while(str[i]!='\0')
    {
        if(str[i] == '(' || str[i] == '[' || str[i] == '{')
            s.push(str[i]);        //若是任意左括号,push
        i++;
    }
    if(IsEmpty(s))
            return true;     //表达式中无括号
    i=0;
    while(str[i]!='\0')
    {
        switch(str[i])
        {
            case ')':
                    if(s.top()!='(')
                        return false;
                    else
                    {
                        s.pop();
                        break;
                    }
                        
            case ']':
                    if(s.top()!='[')
                        return false;
                    else
                    {
                        s.pop();
                        break;
                    }
            case '}':
                    if(s.top()!='{')
                        return false;
                    else
                    {
                        s.pop();
                        break;
                    }
        }
        i++;
    }
    if(!IsEmpty(s))
        return false;
    else 
        return true;        //检查栈中是否还存在单身括号,若存在表达式括号不匹配
}

优化后 ——

#include <stack>

bool check(char str[])
{
    std::stack<char> s;
    int i = 0;
    
    // 遍历字符串,将左括号压入栈中
    while (str[i] != '\0')
    {
        if (str[i] == '(' || str[i] == '[' || str[i] == '{')
        {
            s.push(str[i]);
        }
        else if (str[i] == ')' || str[i] == ']' || str[i] == '}')
        {
            if (s.empty())
                return false;
            
            char topChar = s.top();
            s.pop();
            
            // 匹配对应的括号
            if ((str[i] == ')' && topChar != '(') ||
                (str[i] == ']' && topChar != '[') ||
                (str[i] == '}' && topChar != '{'))
            {
                return false;
            }
        }
        i++;
    }

    // 如果栈不为空,说明还有未匹配的左括号
    return s.empty();
}

5、循环队列元素放在q[1...n]中,实现队列的各种操作

#include <iostream>
#define MAX 100

class CircularQueue {
    int q[MAX];
    int front, rear, size;

public:
    CircularQueue(int n) : front(0), rear(0), size(n) {}

    bool isFull() {
        return (rear + 1) % size == front;
    }

    bool isEmpty() {
        return front == rear;
    }

    void enqueue(int x) {
        if (isFull()) {
            std::cout << "Queue is full\n";
            return;
        }
        q[rear] = x;
        rear = (rear + 1) % size;
    }

    int dequeue() {
        if (isEmpty()) {
            std::cout << "Queue is empty\n";
            return -1;
        }
        int x = q[front];
        front = (front + 1) % size;
        return x;
    }

    int getFront() {
        if (isEmpty()) {
            std::cout << "Queue is empty\n";
            return -1;
        }
        return q[front];
    }
};

6、利用队列将栈中元素逆置的算法

void reverseStack(std::stack<int>& s) {
    std::queue<int> q;

    // 将栈中的元素全部弹出并放入队列中
    while (!s.empty()) {
        q.push(s.top());
        s.pop();
    }

    // 将队列中的元素再依次放回栈中
    while (!q.empty()) {
        s.push(q.front());
        q.pop();
    }
}

 7、递归算法实现数组功能

  1. 求数组中的最大整数
  2. 求数组中n个数的平均值

 求数组中的最大整数:

int findMax(int A[], int n) {
    if (n == 1) 
        return A[0];
    return std::max(A[n-1], findMax(A, n-1));
}

求数组中n个数的平均值:

double findAverage(int A[], int n) {
    if (n == 1)
        return A[0];
    return ((A[n-1] + (n-1) * findAverage(A, n-1)) / n);
}

8、设计递归算法,在一个线性表中搜索指定关键字

      //n为数组长度
int recursiveSearch(int A[], int n, int key) {
    if (n == 0)
        return -1;  // 搜索失败,返回-1
    if (A[n-1] == key)
        return n-1;  // 返回关键字的位置
    return recursiveSearch(A, n-1, key);
}

相关考法 🌈:

  • 栈的应用

    • 1、括号匹配

          • 强化改成switch

    • 2、算术表达式

      • 性质,中缀转前、后缀都有多种形式,为确保算法的确定性,需要规定,后缀“左优先”原则 前缀“右优先”原则

        • 后缀

          • 前缀
             

          • 概要

    • 3、递归

      • 强化学会写递归算法,训练

        • 了解怎么消除斐波那契的重复计算

      • P98,t5、6

    • 顺序栈考题

      • 强化实现共享栈

    • 链栈

      • 强化实现操作

    • 栈选择考题

      • 判断合法性,耐性推就行 进阶:P70,t29

      • 知道一个卡特兰数,用于求个数

 

  • 队列

    • 队列考题

      • 判断合法性(往往双端队列考题多,耐心分析)

      • 知道队头队尾,确定队列元素个数 仔细审题,注意初始条件未必符合常理 p84、t6

        • 1、如图,rear=n-1,p86,t21

        • 2、链队中不带头结点的操作
           

        • 和单链表一块总结

      • 强化

        • 1、实现顺序队判队满的3个方式
          1、Size
          2、tag
          3、rear+1

 

  • 12
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值