【数据结构】6栈

news2025/3/14 9:23:02

0

章节

3.1到3.3小节。

认知与理解栈结构;

列举栈的操作特点。

理解并列举栈的应用案例。

重点

栈的特点与实现;

难点

栈的灵活实现与应用

作业或思考题

完成学习测试2,?

内容达成以下标准(考核点):

        正确实现栈基本操作;

        分析总结栈与队列实现算法;

作业4:栈和队列基本操作

一、题目及分析

1.1题目

有两组型数:A(99,98,89,88,78,78,69,68)和B(89,88,87,86,85,84,83,82,81),

(1)分别建立顺序栈和链栈,来存放A和B,实现数据入栈和出栈操作,输出一种数据元素入栈和对应出栈列表;

(2)分别建立顺序队列和链队列,来存放A和B,实现数据入队和出队操作,输出数据元素入队和出队顺序 ;

1.2分析问题与实现工程类结构图

        题目要求使用顺序栈、链栈、顺序队列和链队列来存放两组数据A和B,并实现相应的入栈、出栈、入队和出队操作。需要分析每种数据结构的特点和操作过程,然后根据题目要求编写相应的代码。

1. 顺序栈(数组):顺序栈是一种使用数组实现的栈,具有先进后出(LIFO)的特点。入栈操作即将数据元素依次添加到栈顶,出栈操作即将栈顶元素移除并返回。入栈操作时,需要判断栈是否已满,若未满则将元素添加到栈顶;出栈操作时,需要判断栈是否为空,若不为空则将栈顶元素移除并返回。由于顺序栈的栈顶位置在数组的末尾,所以入栈、出栈操作的时间复杂度均为O(1)。

2. 链栈:链栈是一种使用链表实现的栈,同样具有先进后出的特点。内存动态分配,无固定大小限制。入栈操作即将数据元素添加到链表的头部,出栈操作即将链表头部元素移除并返回。入栈操作时,需要新建一个节点并将其添加到链表头部;出栈操作时,需要判断链表是否为空,若不为空则将链表头部节点移除并返回。由于链栈的栈顶位置在链表的头部,所以入栈、出栈操作的时间复杂度均为O(1)。

3. 顺序队列(数组):顺序队列是一种使用数组实现的队列,具有先进先出(FIFO)的特点。入队操作即将数据元素添加到队尾,出队操作即将队头元素移除并返回。入队操作时,需要判断队列是否已满,若未满则将元素添加到队尾;出队操作时,需要判断队列是否为空,若不为空则将队头元素移除并返回。由于顺序队列的队头和队尾位置在数组的两端,所以队列的元素位置可能会发生变动,需要使用循环队列来解决这个问题。循环队列可以通过“头尾相接”来实现,入队、出队操作的时间复杂度均为O(1)。

4. 链队列:链队列是一种使用链表实现的队列,同样具有先进先出的特点。入队操作即将数据元素添加到链表的尾部,出队操作即将链表头部元素移除并返回。入队操作时,需要新建一个节点并将其添加到链表尾部;出队操作时,需要判断链表是否为空,若不为空则将链表头部节点移除并返回。由于链队列的队头和队尾位置分别在链表的头部和尾部,所以入队、出队操作的时间复杂度均为O(1)。

        对于每种数据结构,我们需要编写入栈、出栈、入队、出队的代码,并输出数据元素入栈和对应出栈列表,以及数据元素入队和出队的顺序。

1.3工程类结构图

二、类的实现

2.1  SeqStck类代码

package homework4;

//1,顺序栈
public class SeqStack<T> {
   private int maxSize; // 栈的最大容量
   private Object[] stackArray; // 存储栈元素的数组
   private int top; // 栈顶指针,指向栈顶元素的下标

   // 构造方法,初始化栈
   public SeqStack(int size) {
       maxSize = size;
       stackArray = new Object[maxSize];
       top = -1;
   }

   // 判断栈是否为空
   public boolean isEmpty() {
       return top == -1;
   }

   // 判断栈是否已满
   public boolean isFull() {
       return top == maxSize - 1;
   }

   // 入栈操作
   public void push(T data) {
       if (isFull()) {
           System.out.println("栈已满,无法入栈");
           return;
       }
       stackArray[++top] = data;
   }

   // 出栈操作
   public T pop() {
       if (isEmpty()) {
           System.out.println("栈为空,无法出栈");
           return null;
       }
       return (T) stackArray[top--];
   }

}

2.2 LinkedStack类代码

package homework4;

//2,链栈
public class LinkedStack<T> {
   private Node<T> top; // 栈顶节点

   // 构造方法,初始化链栈
   public LinkedStack() {
       top = null;
   }

   // 判断链栈是否为空
   public boolean isEmpty() {
       return top == null;
   }

   // 入栈操作
   public void push(T data) {
       Node<T> newNode = new Node<>(data);
       newNode.next = top;
       top = newNode;
   }

   // 出栈操作
   public T pop() {
       if (isEmpty()) {
           System.out.println("链栈为空,无法出栈");
           return null;
       }
       T data = top.data;
       top = top.next;
       return data;
   }

   // 链栈节点的定义
   private class Node<T> {
       private T data;
       private Node<T> next;

       public Node(T data) {
           this.data = data;
       }
   }
}

2.3 SeqQueue类代码

package homework4;

//3,顺序队列
public class SeqQueue<T> {
   private int maxSize; // 队列的最大容量
   private Object[] queueArray; // 存储队列元素的数组
   private int front; // 队头指针,指向队头元素的下标
   private int rear; // 队尾指针,指向队尾元素的下标的后一个位置

   // 构造方法,初始化队列
   public SeqQueue(int size) {
       maxSize = size;
       queueArray = new Object[maxSize];
       front = rear = 0;
   }

   // 判断队列是否为空
   public boolean isEmpty() {
       return front == rear;
   }

   // 判断队列是否已满
   public boolean isFull() {
       return (rear + 1) % maxSize == front;
   }

   // 入队操作
   public void enqueue(T data) {
       if (isFull()) {
           System.out.println("队列已满,无法入队");
           return;
       }
       queueArray[rear] = data;
       rear = (rear + 1) % maxSize;
   }

   // 出队操作
   public T dequeue() {
       if (isEmpty()) {
           System.out.println("队列为空,无法出队");
           return null;
       }
       T data = (T) queueArray[front];
       front = (front + 1) % maxSize;
       return data;
   }
}

2.4 LinkedQueue类代码

package homework4;

//4,链队列
public class LinkedQueue<T> {
   private Node<T> front; // 队头节点
   private Node<T> rear; // 队尾节点

   // 构造方法,初始化链队列
   public LinkedQueue() {
       front = rear = null;
   }

   // 判断链队列是否为空
   public boolean isEmpty() {
       return front == null;
   }

   // 入队操作
   public void enqueue(T data) {
       Node<T> newNode = new Node<>(data);
       if (isEmpty()) {
           front = rear = newNode;
       } else {
           rear.next = newNode;
           rear = newNode;
       }
   }

   // 出队操作
   public T dequeue() {
       if (isEmpty()) {
           System.out.println("链队列为空,无法出队");
           return null;
       }
       T data = front.data;
       front = front.next;
       if (front == null) {
           rear = null;
       }
       return data;
   }

   // 链队列节点的定义
   private class Node<T> {
       private T data;
       private Node<T> next;

       public Node(T data) {
           this.data = data;
       }
   }
}

2.5 Main类代码

package homework4;

public class Main {
   public static void main(String[] args) {
       // 分别建立顺序栈和链栈来存放A
       SeqStack<Integer> seqStackA = new SeqStack<>(8);
       LinkedStack<Integer> linkedStackA = new LinkedStack<>();
       int[] stackDataA = {99, 98, 89, 88, 78, 78, 69, 68};
       for (int j : stackDataA) {
           seqStackA.push(j);
           linkedStackA.push(j);
       }
       System.out.println("顺序栈A出栈顺序:");
       while (!seqStackA.isEmpty()) {
           System.out.print(seqStackA.pop() + " ");
       }
       System.out.println();
       System.out.println("链栈A出栈顺序:");
       while (!linkedStackA.isEmpty()) {
           System.out.print(linkedStackA.pop() + " ");
       }
       System.out.println();

       // 分别建立顺序队列和链队列来存放B
       SeqQueue<Integer> seqQueueB = new SeqQueue<>(10);
       LinkedQueue<Integer> linkedQueueB = new LinkedQueue<>();
       int[] queueDataB = {89, 88, 87, 86, 85, 84, 83, 82, 81};
       for (int j : queueDataB) {
           seqQueueB.enqueue(j);
           linkedQueueB.enqueue(j);
       }
       System.out.println("顺序队列B出队顺序:");
       while (!seqQueueB.isEmpty()) {
           System.out.print(seqQueueB.dequeue() + " ");
       }
       System.out.println();
       System.out.println("链队列B出队顺序:");
       while (!linkedQueueB.isEmpty()) {
           System.out.print(linkedQueueB.dequeue() + " ");
       }
       System.out.println();
   }
}

三、结果与总结

3.1程序运行结果

3.2总结

        SeqStack类、LinkedStack类、SeqQueue类和LinkedQueue类分别实现了顺序栈、链栈、顺序队列和链队列数据结构。它们的优点和缺点如下:

SeqStack类的优点:

1. 使用数组实现,插入和删除元素的时间复杂度为O(1),具有较高的效率。

2. 对于固定大小的栈,空间利用率较高。

SeqStack类的缺点:

1. 需要预先指定栈的最大容量,如果栈的元素个数超过了容量,会导致栈溢出。

2. 在插入或删除元素时,需要移动其他元素的位置,效率较低。

LinkedStack类的优点:

1. 使用链表实现,插入和删除元素的时间复杂度为O(1),具有较高的效率。

2. 不需要预先指定栈的最大容量,可以根据实际需求动态调整。

LinkedStack类的缺点:

1. 需要额外的内存空间存储链表节点的指针,占用较多的内存。

2. 对于频繁插入或删除元素的操作,可能会导致频繁的内存分配和释放,影响性能。

SeqQueue类的优点:

1. 使用数组实现,循环队列的方式解决了队列满时无法插入元素的问题。

2. 插入和删除元素的时间复杂度为O(1),具有较高的效率。

SeqQueue类的缺点:

1. 需要预先指定队列的最大容量,如果队列的元素个数超过了容量,会导致队列溢出。

2. 在删除元素时,需要移动其他元素的位置,效率较低。

LinkedQueue类的优点:

1. 使用链表实现,插入和删除元素的时间复杂度为O(1),具有较高的效率。

2. 不需要预先指定队列的最大容量,可以根据实际需求动态调整。

LinkedQueue类的缺点:

1. 需要额外的内存空间存储链表节点的指针,占用较多的内存。

2. 对于频繁插入或删除元素的操作,可能会导致频繁的内存分配和释放,影响性能。

3. 在获取队列长度时,需要遍历整个链表,效率较低。

        综上所述,不同的数据结构适用于不同的场景。如果需要固定大小的栈或队列,并且对空间利用率有要求,可以选择SeqStack类和SeqQueue类;如果需要动态调整大小的栈或队列,并且对内存占用有要求,可以选择LinkedStack类和LinkedQueue类。

实验2:栈和队列的应用

一、题目一

1.1题目

编程实现将一个M进制整数转换成N进制数,程序运行时M和N由键盘输入(M和N为正整数),并将一个具体M进制数转成N进制数输出。      

1.2问题的分析

根据题目要求,我们需要将一个M进制整数转换为N进制数。具体而言,需要完成以下几个步骤:

1. 从键盘读取输入的M和N(M和N为正整数)。

2. 从键盘读取输入的M进制整数。

3. 将M进制整数转换为十进制数(使用栈来存储每一位的值,计算时需要按权展开累加)。

4. 将十进制数转换为N进制数(使用队列来存储每一位的值,求余数并入队,再不断整除进队)。

5. 输出转换后的N进制数。

在上述步骤中,我们可以使用栈来实现将M进制整数转换为十进制数,因为栈具有后进先出的特性,适合处理从右到左的操作。而将十进制数转换为N进制数,我们可以使用队列来实现,因为队列具有先进先出的特性,适合处理从左到右的操作。

1.3 工程中类结构图

类BaseConversion,该类包含以下成员变量:

  • num:待转换的M进制整数;
  • M:原进制;
  • N:目标进制;
  • decimalNum:转换为十进制的数字;
  • convertedNum:转换为N进制的结果。

该类可以包含以下方法:

  • 构造函数:接收M进制整数、原进制和目标进制,将M进制整数转换为十进制数,并将十进制数转换为目标进制数;
  • convertToDecimal方法:接收M进制整数和原进制,将M进制整数转换为十进制数,并使用栈来辅助计算;
  • convertFromDecimal方法:接收十进制数和目标进制,将十进制数转换为目标进制数,并使用队列来辅助计算;
  • charToInt方法:将一个字符转换为对应的整数;
  • intToChar方法:将一个整数转换为对应的字符;
  • printResult方法:输出转换后的N进制数。

类Test1

        在主函数中,可以从键盘读取输入的M和N值以及M进制数,然后创建一个BaseConversion对象进行转换,最后输出转换后的N进制数。

1.4各个类的实现

        通过BaseConversion类中的convertToDecimal和convertFromDecimal函数将M进制数转换为十进制数,再将十进制数转换为N进制数。在main函数中,先读取输入的M和N值以及M进制数,然后创建一个BaseConversion对象进行转换,最后输出转换后的N进制数。

        首先定义了BaseConversion类,该类包含了num(待转换的M进制整数)、M(原进制)、N(目标进制)、decimalNum(转换为十进制的数字)和convertedNum(转换为N进制的结果)等成员变量。

        在构造函数中,将输入的M进制整数转换为十进制数,并将十进制数转换为N进制数。

        convertToDecimal方法使用了栈来辅助计算,从num的最后一位开始,通过charToInt将字符转换为对应的数字,并根据M的幂次进行累加得到十进制数。

        convertFromDecimal方法使用了队列来辅助计算,通过不断将十进制数除以N,得到余数并入队列,直到十进制数变为0。然后依次出队列,通过intToChar将数字转换为对应的字符,构建出N进制数的字符串表示。

        接着是定义了charToInt方法和intToChar方法,用于字符和数字的相互转换。

        在printResult方法中,输出转换后的N进制数。

        最后,在Test1类的main函数中,从键盘读取输入的M和N,并输入待转换的M进制整数。然后创建一个BaseConversion对象,并传入参数进行转换。最后调用printResult方法输出转换后的结果。

1.4.1 BaseConversion类代码
package experience2;

import java.util.Stack;
import java.util.Queue;
import java.util.LinkedList;

public class BaseConversion {
   private String num;
   private int M;
   private int N;
   private int decimalNum;
   private String convertedNum;

   public BaseConversion(String num, int M, int N) {
       this.num = num;
       this.M = M;
       this.N = N;
       // 将输入的M进制整数转换为十进制数
       decimalNum = this.convertToDecimal(num, M);
       // 将十进制数转换为N进制数
       convertedNum = this.convertFromDecimal(decimalNum, N);

   }

   // 将一个M进制整数转换为十进制数
   public static int convertToDecimal(String num, int M) {
       int decimalNum = 0;
       int power = 1;
       Stack<Integer> stack = new Stack<>();

       for (int i = num.length() - 1; i >= 0; i--) {
           int digit = charToInt(num.charAt(i));
           decimalNum += digit * power;
           power *= M;
       }
       return decimalNum;
   }

   // 将一个十进制数转换为N进制数
   public static String convertFromDecimal(int decimalNum, int N) {
       Queue<Integer> queue = new LinkedList<>();

       while (decimalNum > 0) {
           int remainder = decimalNum % N;
           queue.offer(remainder);
           decimalNum /= N;
       }

       StringBuilder sb = new StringBuilder();
       while (!queue.isEmpty()) {
           sb.append(intToChar(queue.poll()));
       }
       return sb.toString();
   }

   // 将一个字符转换为对应的整数
   private static int charToInt(char ch) {
       if (ch >= '0' && ch <= '9') {
           return ch - '0';
       } else {
           return ch - 'A' + 10;
       }
   }

   // 将一个整数转换为对应的字符
   private static char intToChar(int num) {
       if (num >= 0 && num <= 9) {
           return (char) ('0' + num);
       } else {
           return (char) ('A' + num - 10);
       }
   }

   public void printResult () {
       // 输出转换后的N进制数
       System.out.println(num + "的" + N + "进制表示为:" + convertedNum);
   }
}
1.4.2  Test1类代码
package experience2;

import java.util.Scanner;

public class Test1 {
   public static void main(String[] args) {
       // 从键盘读取输入的M和N
       Scanner scanner = new Scanner(System.in);
       System.out.println(">=======将一个M进制整数转换成N进制数========<");
       System.out.print("请输入M的值:");
       int M = scanner.nextInt();
       System.out.print("请输入N的值:");
       int N = scanner.nextInt();

       // 从键盘读取输入的M进制整数
       System.out.print("请输入一个M进制整数:");
       String num = scanner.next();


       // 创建一个BaseConversion对象,并传入参数
//        BaseConversion bc = new BaseConversion("123", 8, 2);
       BaseConversion bc = new BaseConversion(num, M, N);
       //输出结果, 输出转换后的N进制数
       bc.printResult();
   }
}

1.5程序运行结果

二、题目二

2.1题目

        数据结构是一门较难的课程,同学们学习时问题较多,请你编写一个课程答疑程序,对多个同学的问题进行一一解答。

2.2问题的分析

        这个程序的主要目标是模拟一个课堂答疑环境。在这个环境中,学生可以提出问题,问题被放入一个队列中,然后老师从队列中取出问题并回答。

这个程序的设计涉及到几个主要的问题:

1. 如何表示学生和问题?

创建了一个学生类和一个问题类来解决这个问题。学生类包含学生的姓名、编号和他们提出的问题列表。问题类包含提问者和问题内容。

2. 如何存储问题?

使用一个循环队列来存储问题。循环队列是一种特殊的队列,当队列满时,新的元素会被添加到队列的开头。这种数据结构非常适合模拟这个问题,因为它可以保证问题按照先进先出的顺序被回答。

3. 如何处理问题?

创建学生对象和问题对象,然后将问题添加到循环队列中。然后,使用一个循环,从队列中取出问题并回答,直到队列为空。

需求:

1. 需要定义一个学生类(Student),包含学生的姓名、学号和问题列表。

2. 需要定义一个问题类(Question),包含提问者(学生对象)和问题内容。

3. 需要定义一个循环队列类(CircularQueue),实现队列接口(QueueInterface),用于存储学生的问题。

4. 主类(Main)中,创建循环队列对象和多个学生对象,并将学生的问题加入队列中。

5. 使用循环队列模拟老师回答问题的过程,从队列中取出问题并进行回答。

2.3工程中类结构图

程序包括以下几个部分:

1. 接口QueueInterface:定义了队列的基本操作,包括入队、出队、获取队头元素和判断队列是否为空。

2. 类CircularQueue:实现了QueueInterface接口,代表一个循环队列。它使用数组实现队列,并记录了队列的大小、队头和队尾指针。具体的功能包括入队、出队、获取队头元素和判断队列是否为空。

3. 类Question:代表一个问题,包含提问者和问题内容。它提供了输出问题信息的方法。

4. 类Student:代表一个学生,包含学号、姓名和问题列表。它提供了添加问题和输出学生信息的方法。

5. 主类Main:在main方法中创建了一个CircularQueue对象和两个Student对象,并将学生的问题加入队列中。然后通过循环从队列中取出问题并回答。

程序的运行逻辑如下:

1. 创建循环队列对象queue。

2. 创建两个Student对象s1和s2,并为每个学生添加问题。

3. 将学生的问题加入队列中。

4. 循环从队列中取出问题,回答问题,并输出回答内容。

2.4各个类的实现

2.4.1 CircularQueue类代码
package experience2.t2;

// 定义循环队列,实现接口
public class CircularQueue<T> implements Queue<T> {
   private T[] queue;
   private int size;
   int front, rear;

   public CircularQueue() {
       front = rear = 0;
       size = 5;
       queue = (T[]) (new Object[size]);
   }

   void setSize(int n) {
       this.size = n;
   }

   public void enterQueue(T element) {
       if ((rear + 1) % size == front) {
           System.out.print("队列满");
           return;
       }
       queue[rear] = element;
       rear = (rear + 1) % size;
       System.out.println("  front=" + front + ",rear=" + rear);
   }

   public T delQueue() {
       if (isEmpty()) {
           System.out.print("队空");
           return null;
       }
       T queueHead = queue[front];
       front = (front + 1) % size;
       System.out.println("  front=" + front + ",rear=" + rear);
       return queueHead;
   }

   public T getHead() {
       if (isEmpty()) {
           System.out.print("队空");
           return null;
       }
       T queueHead = queue[front + 1];
       System.out.println("  front=" + front + ",rear=" + rear);
       return queueHead;
   }

   public boolean isEmpty() {
       return rear == front;
   }
}

2.4.2  Question类代码

package experience2.t2;

public class Question {
   Student asker;
   String content;

   public Question(Student asker, String content) {
       this.asker = asker;
       this.content = content;
   }

   public void outInformation() {
       System.out.println("来自 " + asker.name + " 的问题: " + content);
   }
}

2.4.3  Queue接口代码

package experience2.t2;

// 定义接口规范队列完成功能
public interface Queue<T> {
   void enterQueue(T element);

   T delQueue();

   T getHead();

   boolean isEmpty();
}
2.4.4  Student类代码
package experience2.t2;

import java.util.ArrayList;
import java.util.List;

public class Student {
   String num;
   String name;
   List<Question> questions;

   public Student(String name, String num) {
       this.num = num;
       this.name = name;
       this.questions = new ArrayList<>();
   }

   public void addQuestion(Question question) {
       this.questions.add(question);
   }

   public void outInformation() {
       System.out.println(name + "," + num);
   }
}
2.4.5  Test2类代码
package experience2.t2;

public class Test2 {
   public static void main(String[] args) {
       CircularQueue<Question> queue = new CircularQueue<>();

       Student s1 = new Student("LiMing", "123456789");
       s1.addQuestion(new Question(s1, "数据结构是什么?"));
       s1.addQuestion(new Question(s1, "队列是如何工作的?"));

       Student s2 = new Student("YiMing", "2323345");
       s2.addQuestion(new Question(s2, "什么是栈?"));
       s2.addQuestion(new Question(s2, "二叉树是如何工作的?"));

       // 学生提问
       for (Question question : s1.questions) {
           queue.enterQueue(question);
       }
       for (Question question : s2.questions) {
           queue.enterQueue(question);
       }

       // 老师回答问题
       while (!queue.isEmpty()) {
           Question question = queue.delQueue();
           System.out.println("回答问题: ");
           question.outInformation();
           System.out.println("回答: 这是一个好问题。");
       }
   }
}

2.5程序运行结果

三 实验总结

3.1对于问题一

1:如何将M进制数转换为十进制数?

解决方案:使用栈来辅助计算。从M进制数的最后一位开始,通过charToInt方法将字符转换为对应的数字,并根据M的幂次进行累加得到十进制数。

2:如何将十进制数转换为N进制数?

解决方案:使用队列来辅助计算。通过不断将十进制数除以N,得到余数并入队列,直到十进制数变为0。然后依次出队列,通过intToChar方法将数字转换为对应的字符,构建出N进制数的字符串表示。

3:如何将字符转换为对应的整数?

解决方案:使用charToInt方法将字符转换为对应的整数。如果字符是数字,则将其减去字符'0'的ASCII码值;如果字符是字母,则将其减去字符'A'的ASCII码值再加上10。

4:如何将整数转换为对应的字符?

解决方案:使用intToChar方法将整数转换为对应的字符。如果整数在0到9之间,则将其加上字符'0'的ASCII码值;如果整数在10到35之间,则将其加上字符'A'的ASCII码值再减去10。

在程序实现过程中,采用了面向对象的编程思想,将转换的逻辑封装在BaseConversion类中,并且通过构造函数进行初始化。这样做的好处是可以重复使用该类,并且提高代码的可读性和可维护性。

程序的优点:

1. 可以实现将任意M进制整数转换为N进制数,具有一定的通用性。

2. 使用栈和队列来辅助计算,遵循了栈先进后出和队列先进先出的特点,使得转换过程更加简洁明了。

3. 代码结构清晰,函数划分合理,易于理解和维护。

程序的缺点:

1. 没有对用户输入的数据进行验证和异常处理,如果输入的M和N不是正整数或M进制数中包含非法字符,程序可能会出现错误。

2. 对于大数字的计算可能存在效率问题,因为使用了栈和队列来存储每一位的值,当数字很大时,可能会占用较多的内存空间。

3. 在实际使用中,需要注意对输入数据的验证和异常处理,以及对大数字的计算效率优化。

3.2对于问题二

在这个实验中,我们实现了一个循环队列和学生提问的模拟。通过这个实验,我遇到了一些问题并找到了解决方法。

问题1:为什么要使用循环队列?

解决方法:循环队列可以有效地利用存储空间,通过循环利用数组空间来实现队列的功能。当队列满时,可以将队尾指针重新指向队首,实现循环利用。

问题2:如何判断队列是否为空?

解决方法:我们可以通过判断队首指针和队尾指针是否相等来判断队列是否为空。如果相等,则表示队列为空。

问题3:为什么需要定义Question类和Student类?

解决方法:Question类表示学生的问题,包含提问者和问题内容两个属性。Student类表示学生,包含姓名、学号和问题列表三个属性。通过定义这两个类,我们可以将学生的问题与学生进行关联,并方便地管理学生的问题。

程序优点:

1. 实现了循环队列的基本功能,包括入队、出队、获取队首元素和判断队列是否为空。

2. 分别定义了Question类和Student类,使得代码结构清晰,易于理解和扩展。

3. 使用了泛型,可以适应不同类型的队列元素。

程序缺点:

1. 循环队列的大小是固定的,无法动态扩容。如果队列已满,再添加元素会导致队列溢出。

2. 没有提供删除指定元素的功能,只能删除队首元素。

3. 在CircularQueue类中,没有提供获取队尾元素的方法,只能通过出队操作来获取队尾元素。

4. 没有对输入进行严格的校验,比如在enterQueue()方法中,没有判断element是否为null。

通过这个实验,我学习了循环队列的实现原理和相关操作。在今后的编程实践中,我会更加注重程序的可扩展性和灵活性,同时注意处理边界情况和异常情况,提高程序的健壮性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2314782.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PyTorch 入门学习

目录 PyTorch 定义 核心作用 应用场景 Pytorch 基本语法 1. 张量的创建 2. 张量的类型转换 3. 张量数值计算 4. 张量运算函数 5. 张量索引操作 6. 张量形状操作 7. 张量拼接操作 8. 自动微分模块 9. 案例-线性回归案例 PyTorch 定义 PyTorch 是一个基于 Python 深…

mov格式视频如何转换mp4?

mov格式视频如何转换mp4&#xff1f;在日常的视频处理中&#xff0c;经常需要将MOV格式的视频转换为MP4格式&#xff0c;以兼容更多的播放设备和平台。下面给大家分享如何将MOV视频转换为MP4&#xff0c;4款视频格式转换工具分享。 一、牛学长转码大师 牛学长转码大师是一款功…

二进制求和(js实现,LeetCode:67)

这道题我的解决思路是先将a和b的长度保持一致以方便后续按位加减 let lena a.length let lenb b.length if (lena ! lenb) {if (lena > lenb) {for (let i 0; i <lena-lenb; i) {b 0 b}} else {for (let i 0; i < lenb-lena; i) {a 0 a}} } 下一步直接进行按…

【C#】使用DeepSeek帮助评估数据库性能问题,C# 使用定时任务,每隔一分钟移除一次表,再重新创建表,和往新创建的表追加5万多条记录

&#x1f339;欢迎来到《小5讲堂》&#x1f339; &#x1f339;这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。&#x1f339; &#x1f339;温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01;&#…

【openGauss】物理备份恢复

文章目录 1. gs_backup&#xff08;1&#xff09;备份&#xff08;2&#xff09;恢复&#xff08;3&#xff09;手动恢复的办法 2. gs_basebackup&#xff08;1&#xff09;备份&#xff08;2&#xff09;恢复① 伪造数据目录丢失② 恢复 3. gs_probackup&#xff08;1&#xf…

蓝桥杯备赛-基础练习 day1

1、闰年判断 问题描述 给定一个年份&#xff0c;判断这一年是不是闰年。 当以下情况之一满足时&#xff0c;这一年是闰年:1.年份是4的倍数而不是100的倍数 2&#xff0e;年份是400的倍数。 其他的年份都不是闰年。 输入格式 输入包含一个…

实验四 Python聚类决策树训练与预测 基于神经网络的MNIST手写体识别

一、实验目的 Python聚类决策树训练与预测&#xff1a; 1、掌握决策树的基本原理并理解监督学习的基本思想。 2、掌握Python实现决策树的方法。 基于神经网络的MNIST手写体识别&#xff1a; 1、学习导入和使用Tensorflow。 2、理解学习神经网络的基本原理。 3、学习使用…

【原创】在高性能服务器上,使用受限用户运行Nginx,充当反向代理服务器[未完待续]

起因 在公共高性能服务器上运行OllamaDeepSeek&#xff0c;如果按照默认配置启动Ollama程序&#xff0c;则自己在远程无法连接你启动的Ollama服务。 如果修改配置&#xff0c;则会遇到你的Ollama被他人完全控制的安全风险。 不过&#xff0c;我们可以使用一个方向代理&#…

Spring boot3-WebClient远程调用非阻塞、响应式HTTP客户端

来吧&#xff0c;会用就行具体理论不讨论 1、首先pom.xml引入webflux依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId> </dependency> 别问为什么因为是响应式....…

18 | 实现简洁架构的 Handler 层

提示&#xff1a; 所有体系课见专栏&#xff1a;Go 项目开发极速入门实战课&#xff1b;欢迎加入 云原生 AI 实战 星球&#xff0c;12 高质量体系课、20 高质量实战项目助你在 AI 时代建立技术竞争力&#xff08;聚焦于 Go、云原生、AI Infra&#xff09;&#xff1b;本节课最终…

coding ability 展开第三幕(滑动指针——基础篇)超详细!!!!

文章目录 前言滑动窗口长度最小的子数组思路 无重复字符的最长子串思路 最大连续1的个数思路 将x减到0的最小操作数思路 总结 前言 前面我们已经把双指针的一些习题练习的差不多啦 今天我们来学习新的算法知识——滑动窗口 让我们一起来探索滑动窗口的魅力吧 滑动窗口 滑动窗口…

如何自己做奶茶,从此告别奶茶店

自制大白兔奶茶&#xff0c;奶香与茶香激情碰撞&#xff0c;每一口都是香浓与甜蜜的双重诱惑&#xff0c;好喝到跺脚&#xff01;丝滑口感在舌尖舞动&#xff0c;仿佛味蕾在开派对。 简单几步就能复刻&#xff0c;成本超低&#xff0c;轻松在家享受奶茶自由。 材料:大白兔奶糖&…

宇树人形机器人开源模型

1. 下载源码 https://github.com/unitreerobotics/unitree_ros.git2. 启动Gazebo roslaunch h1_description gazebo.launch3. 仿真效果 H1 GO2 B2 Laikago Z1 4. VMware: vmw_ioctl_command error Invalid argument 这个错误通常出现在虚拟机环境中运行需要OpenGL支持的应用…

【Linux】浅谈冯诺依曼和进程

一、冯诺依曼体系结构 冯诺依曼由 输入设备、输出设备、运算器、控制器、存储器 五部分组成。 冯诺依曼的设计特点 二进制表示 所有数据&#xff08;包括程序指令&#xff09;均以二进制形式存储和运算&#xff0c;简化了硬件逻辑设计&#xff0c;提高了可靠性。 存储程序原理…

linux操作系统实战

第一题 创建根目录结构中的所有的普通文件 [rootlocalhost ~]# cd /[rootlocalhost /]# mkdir /text[rootlocalhost /]# cd /text[rootlocalhost text]# mkdir /text/boot /text/root /text/home /text/bin /text/sbin /text/lib /text/lib64 /text/usr /text/opt /text/etc /…

浅谈时钟启动和Systemlnit函数

时钟是STM32的关键&#xff0c;是整个系统的心脏&#xff0c;时钟如何启动&#xff0c;时钟源如何选择&#xff0c;各个参数如何设置&#xff0c;我们从源码来简单分析一下时钟的启动函数Systemlnit&#xff08;&#xff09;。 Systemlnit函数简介 我们先来看一下源程序的注释…

MySql学习_基础Sql语句

目录 1.数据库相关概念 2.SQL 2.1 SQL通用语法 2.2 SQL分类 2.3 DDL&#xff08;数据库定义语言&#xff09; 2.4 DML&#xff08;数据操作语言&#xff09; 2.5 DQL&#xff08;数据查询语言&#xff09; 2.6 DCL&#xff08;数据控制语言&#xff09; 3. 函数 3.1 字…

小白学Agent技术[5](Agent框架)

文章目录 Agent框架Single Agent框架BabyAGIAutoGPTHuggingGPTHuggingGPT工作原理说明GPT-EngineerAppAgentOS-Copilot Multi-Agent框架斯坦福虚拟小镇TaskWeaverMetaGPT微软UFOAgentScope现状 常见Agent项目比较概述技术规格和能力实际应用案例开发体验比较ChatChain模式 Agen…

VSTO(C#)Excel开发4:打印设置

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…

设计模式Python版 模板方法模式(上)

文章目录 前言一、模板方法模式二、模板方法模式示例 前言 GOF设计模式分三大类&#xff1a; 创建型模式&#xff1a;关注对象的创建过程&#xff0c;包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式&#xff1a;关注类和对象之间…