数据结构和算法02--队列
2021/4/13 12:27:48
本文主要是介绍数据结构和算法02--队列,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
队列:先进先出、用链表或数组实现。
一、一般的队列
1、思路:
模拟简单队列——队首走的位置不能再添加。
实现方式:两个指针,一个指向队首front、一个指向队尾rear。指向队首的负责取出数据,指向队尾的负责添加数据。
难点:在于添加和取出数据时,指针应先操作该位置数据然后再移动指针,不然指针就没了。
2、代码
代码实现思路:先创建数组队列-->添加判断为空、已满、放入数据、取出数据、遍历队列、查看头节点的方法-->main方法写测试代码。
//测试最基本的队列 public class BasicQueue01 { //9、创建主方法用于测试 public static void main(String[] args) { //创建一个队列 ArrayQueue arrQueue = new ArrayQueue(4); //用于接收用户输入信息 char key = ' '; Scanner scanner = new Scanner(System.in); boolean loop = true; while(loop) { System.out.println("s(show): 显示队列"); System.out.println("e(exit): 退出程序"); System.out.println("a(add): 添加数据到队列"); System.out.println("g(get): 从队列取出数据"); System.out.println("h(head): 查看队列头的数据"); key = scanner.next().charAt(0); switch(key) { case 's': arrQueue.showQueue(); break; case 'a': System.out.println("请输入一个数"); int value = scanner.nextInt(); arrQueue.addQueue(value); break; case 'g': try { int num = arrQueue.getQueue(); System.out.println(num); }catch(RuntimeException e) { System.out.println(e.getMessage()); } break; case 'h': try { int headQueue = arrQueue.headQueue(); System.out.println("第一个数据是" + headQueue); }catch(RuntimeException e) { System.out.println(e.getMessage()); } break; case 'e': scanner.close(); loop = false; default: break; } } System.out.println("程序退出啦"); } } class ArrayQueue{ //1、先给出队列的各种属性 private int maxSize; private int front; private int rear; private int[] arr; //2、给一个队列的构造方法 public ArrayQueue(int arrmaxSize) { maxSize = arrmaxSize; front = -1; rear = -1; arr = new int[maxSize]; } //3、判断队列是否已满 public boolean isFull() { return rear == maxSize - 1; } //4、判断队列是否为空 public boolean isEmpty() { return rear == front; } //5、添加数据到队列 public void addQueue(int n) { //(1)先判断队列是否已满 if(isFull()) { System.out.println("队列已满,不能添加~~"); return; } //(2)如果不满的话,那就在后面加一格,然后加数据 rear++; arr[rear] = n; } //6、获取队列的数据,出队列 public int getQueue() { //(1)先判断队列是否为空 if(isEmpty()) { throw new RuntimeException("队列为空,不能获取~~"); } //(2)如果不为空的话,那就把指向第一个的前面这个指针,指向第一个,然后取出来,以此类推 front++; return arr[front]; } //7、查询队列 public void showQueue() { if (isEmpty()) { System.out.println("队列空的,没有数据~~"); return; } for(int i = 0;i < arr.length;i++) { System.out.printf("arr[%d]=%d\n",i+1,arr[i]); } System.out.println(); } //8、显示队列的头数据 public int headQueue() { if(isEmpty()) { throw new RuntimeException("队列为空,无法显示"); } return arr[front+1]; } }
二、循环队列
1、思路
解决普通队列不能不能在前面位置再添加的问题。
改成环形队列这样就可以反复添加了。
但是这里要注意到最大值后就返回到初始值了。
实现方式:front、rear指针,每添加一个rear指向当前位置后一个,浪费一个元素,指到最后一个元素为满。
难点:因为满了又跳到0,所以得注意front/rear + 1可能回到初始位置,并且得注意rear - front可能存在小减大的情况,所以判断有几个元素的时候不能直接用rear - front的方式。
2、代码
代码实现思路:先创建数组队列-->添加判断为空、已满、放入数据、取出数据、遍历队列、查看头节点的方法-->main方法写测试代码。
//测试环形队列 public class CircleArrayQueue01 { public static void main(String[] args) { System.out.println("测试数组模拟环形队列的案例~~~"); CircleQueue circleQueue = new CircleQueue(4); char key = ' '; Scanner scanner = new Scanner(System.in); boolean loop = true; while(loop) { System.out.println("s(show): 显示队列"); System.out.println("e(exit): 退出程序"); System.out.println("a(add): 添加数据到队列"); System.out.println("g(get): 从队列取出数据"); System.out.println("h(head): 查看队列头的数据"); key = scanner.next().charAt(0); switch(key) { case 's': circleQueue.showQueue(); break; case 'a': System.out.println("请输入一个数"); int num = scanner.nextInt(); circleQueue.addQueue(num); break; case 'g': try { int result = circleQueue.getQueue(); System.out.printf("查到的数据是%d\n",result); }catch(RuntimeException e) { System.out.println(e.getMessage()); } break; case 'h': int result = circleQueue.headQueue(); System.out.printf("查到的数据是%d\n",result); break; case 'e': scanner.close(); loop = false; break; default: break; } } System.out.println("退出程序~~"); } } class CircleQueue{ //属性 private int maxSize; private int front; private int rear; private int[] arr; //构造函数 public CircleQueue(int arrMaxSize) { maxSize = arrMaxSize; arr = new int[maxSize]; } //判断是否为空 public boolean isEmpty() { return rear == front; } //判断是否已满 public boolean isFull() { return (rear + 1) % maxSize == front; } //添加数列到队列 public void addQueue(int num) { if(isFull()) { System.out.println("队列已满,无法加入"); return; } arr[rear] = num; rear = (rear + 1) % maxSize; } //获取队列数据,出队列 public int getQueue() { if(isEmpty()) { throw new RuntimeException("队列为空,不能取数据"); } int value = arr[front]; front = (front + 1)% maxSize; return value; } //显示队列所有数据 public void showQueue() { if(isEmpty()) { System.out.println("队列为空,不能显示"); return; } for(int i = front;i < front + size() ;i++) { System.out.printf("arr[%d] = %d\n",i%maxSize,arr[i%maxSize]); } } //求出当前队列的有效数据 public int size() { return (rear + maxSize - front) % maxSize; } //显示队列的头数据 public int headQueue() { if(isEmpty()) { throw new RuntimeException("队列为空,没有数据"); } return arr[front]; } }
这篇关于数据结构和算法02--队列的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-28一步到位:购买适合 SEO 的域名全攻略
- 2024-12-27OpenFeign服务间调用学习入门
- 2024-12-27OpenFeign服务间调用学习入门
- 2024-12-27OpenFeign学习入门:轻松掌握微服务通信
- 2024-12-27OpenFeign学习入门:轻松掌握微服务间的HTTP请求
- 2024-12-27JDK17新特性学习入门:简洁教程带你轻松上手
- 2024-12-27JMeter传递token学习入门教程
- 2024-12-27JMeter压测学习入门指南
- 2024-12-27JWT单点登录学习入门指南
- 2024-12-27JWT单点登录原理学习入门