数据结构(7)--队列
来源:互联网 发布:linux tomcat自动关闭 编辑:程序博客网 时间:2024/06/06 02:10
对于Queue这个词大家熟悉么?我相信学习Android对于这个词熟悉的程度可谓是极深,毕竟Android内部很多的实现都是靠着队列.Handler、service内部实现也是.其实在我们生活当中,队列的作用就类似于说,我们去排队打饭(原谅我这个吃货),肯定是有人从前面打完饭走了,有人从后面排队进来…这样就是一个队列,那么大家都可以看出其中的特点了吧.
队列(简称作队,Queue)也是一种特殊的线性表,队列的数据元素以及数据元素间的逻辑关系和线性表完全相同,其差别是线性表允许在任意位置插入和删除,而队列只允许在其一端进行插入操作在其另一端进行删除操作。
队列中允许进行插入操作的一端称为队尾,允许进行删除操作的一端称为队头。队列的插入操作通常称作入队列,队列的删除操作通常称作出队列。
英文为:FIFO—>First In First Out,先进先出,后进后出
注意:队列也是有有着头结点(front)和队尾结点(rear)的.
队列的顺序存储:
在顺序存储里面,我们会经常发生”假溢出”现象.
front指向头元素,rear指向尾元素的下一个位置.因为顺序队列是限定个数,所以一旦前面的全部出去了,front后移,但是后面的插进来,会发现越界,但是实际上前面还有空位.这就是假溢出.
解决假溢出,就需要通过循环队列,循环队列的意思就是头尾相接,但是头尾相接又会出现一个循环有可能为空的问题,所以我们的解决方法是通过计数器的方法,来判定.
代码:
public class ListQueue { static final int defaultSize = 10; //默认队列的长度 int front; //队头 int rear; //队尾 int count; //统计元素个数的计数器 int maxSize; //队的最大长度 Object[] queue; //队列 public ListQueue() { init(defaultSize); } public ListQueue(int size) { init(size); } public void init(int size) { maxSize = size; front = rear = 0; count = 0; queue = new Object[size]; } public void append(Object obj) throws Exception { // TODO Auto-generated method stub if (count > 0 && front == rear) { throw new Exception("队列已满!"); } //添加到尾节点 queue[rear] = obj; rear = (rear + 1) % maxSize; count++; } //从头结点删除,并且作为一个循环了实用front public Object delete() throws Exception { // TODO Auto-generated method stub if (isEmpty()) { throw new Exception("队列为空!"); } Object obj = queue[front]; front = (front + 1) % maxSize; count--; return obj; } public Object getFront() throws Exception { // TODO Auto-generated method stub if (!isEmpty()) { return queue[front]; } else { return null; } } public boolean isEmpty() { // TODO Auto-generated method stub return count == 0; } /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { // TODO Auto-generated method stub ListQueue queue = new ListQueue(); queue.append("a"); queue.append("b"); queue.append("c"); queue.append("d"); queue.append("e"); queue.append("f"); queue.delete(); queue.delete(); while (!queue.isEmpty()) { System.out.println(queue.delete()); } } } 链式队列: 链式队列其实就是特殊的单链表,只不过它只能尾进头出而已.说到链式队列,我们第一想到的就是结点的不同,我们要安排结点的构造. 结点类我就不写了: 测试类:(主要关注我们的front rear的变化就好了) private QueueNode<T> front,rear;//声明两个结点 public LinkedQueue() { this(null); } //初始化结点 public LinkedQueue(T element) { if(element == null) { front = new QueueNode<T>(null); rear = front; }else { rear = new QueueNode<T>(element); front = new QueueNode<T>(null,rear); } } public int length(){ if(isEmpty()) return 0; int k=1; QueueNode<T> temp = front.getNext(); while(temp!=rear){ k++; temp=temp.getNext(); } return k; } //获取第一个元素 public T getHead() { if(isEmpty()) return null; return front.getNext().getData(); } //判断空 public boolean isEmpty() { return front == rear; } //加入元素,从后面加入 public boolean add(T element) { if(element == null) return false; QueueNode<T> temp = front; rear.setNext(new QueueNode<T>(element)); rear = rear.getNext(); return true; } //移除元素,前面走人,所以要对front进行修改 public T remove() { if(isEmpty()) return null; T element = front.getNext().getData(); if(length() == 1) rear = front; else{ front.setNext(front.getNext().getNext()); } return element; } //目标转换成字符串,拼接 public String toString() { if(isEmpty()) return "[ ]"; StringBuffer sb = new StringBuffer("[ "); QueueNode<T> temp = front.getNext(); while(temp != rear) { sb.append(temp+" "); temp = temp.getNext(); } sb.append(temp+" "); sb.append("]"); return sb.toString(); } public static void main(String[] args) { // TODO Auto-generated method stub LinkedQueue<String> queue = new LinkedQueue<String>("A"); System.out.println("queue="+queue+" queue.length="+queue.length()); queue.add("B"); System.out.println("queue="+queue+" queue.length="+queue.length()); System.out.println("the removint element="+queue.remove()); System.out.println("queue="+queue+" queue.length="+queue.length()); }
相信大家在查询的时候,会遇到一些类似与优先队列,其实优先队列的实现是差不多的,基本上就是我们逻辑上会多出一个优先级变量来设定优先级.
面试题:
设计含最小函数min()的栈,要求min、push、pop、的时间复杂度都是O(1)?
思路:
这里需要加一个辅助栈,用空间换取时间。辅助栈中,栈顶永远保存着当前栈中最小的数值。具体是这样的:原栈中,每次添加一个新元素时,就和辅助栈的栈顶元素相比较,如果新元素小,就把新元素的值放到辅助栈中,如果新元素大,就把辅助栈的栈顶元素再copy一遍放到辅助栈的栈顶;
重点方法:
minStack.peek()—>获取栈顶元素.
import java.util.Stack;/** * Created by smyhvae on 2015/9/9. */public class MinStack { private Stack<Integer> stack = new Stack<Integer>(); private Stack<Integer> minStack = new Stack<Integer>(); //辅助栈:栈顶永远保存stack中当前的最小的元素 public void push(int data) { stack.push(data); //直接往栈中添加数据 //在辅助栈中需要做判断 if (minStack.size() == 0 || data < minStack.peek()) { minStack.push(data); } else { minStack.add(minStack.peek()); //【核心代码】peek方法返回的是栈顶的元素 } } public int pop() throws Exception { if (stack.size() == 0) { throw new Exception("栈中为空"); } int data = stack.pop(); minStack.pop(); //核心代码 return data; } public int min() throws Exception { if (minStack.size() == 0) { throw new Exception("栈中空了"); } return minStack.peek(); } public static void main(String[] args) throws Exception { MinStack stack = new MinStack(); stack.push(4); stack.push(3); stack.push(5); System.out.println(stack.min()); }}
- 数据结构(7)--队列
- 数据结构---队列
- 数据结构--队列
- 数据结构队列
- 数据结构---队列
- 数据结构(队列)
- 数据结构-队列
- 数据结构---->队列
- 数据结构---队列
- 【数据结构】队列
- 数据结构--队列
- 【数据结构】 队列
- 数据结构 -- 队列
- 数据结构--队列
- 数据结构:队列
- 数据结构 队列
- 数据结构----队列
- 数据结构----队列
- 蓝牙Ble基础
- 委托概念(难点)
- (16)Struts2_OGNL读取Map栈及其他字段和方法属性
- OKHttp源码分析2 - Request的创建和发送
- 操作系统-进程
- 数据结构(7)--队列
- 决策树
- 数据结构(8)--树
- React-Native入门指导之iOS篇 —— 一、准备工作
- 【微信服务号】ngrok内网穿透
- case语句
- Ubuntu 16.04查看软件安装位置
- 下拉菜单的实现(一)
- ubuntu关机命令