队列(queue)
队列 是一种先进先出的线性表,它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
优先队列(priority queue),普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除,具有最高级先出 (largest-in,first-out)的行为特征。
用数组实现顺序队列的实现:
package test; public class Queue { // 数组 private long[] arr; // 最大空间 private int maxSize; // 有效元素大小 private int elems; // 队头 private int font; // 队尾 private int end; public Queue(){} public Queue(int maxSize) { this.maxSize = maxSize; arr = new long[maxSize]; elems = 0; font = 0; end = -1; } // 插入数据 public void insert(long value) { arr[++end] = value; elems++; } // 移除数据 public long remove() { elems--; return arr[font++]; } // 是否为空 public boolean isEmpty() { return (elems == 0); } // 是否满了 public boolean isFull() { return (end == maxSize - 1); } // 返回有效元素大小 public int size() { return elems; } }
测试:
@Test public void fun1() { Queue queue = new Queue(5); queue.insert(4); queue.insert(9); queue.insert(7); System.out.println("删除数据:"+queue.remove()+"队列大小:"+queue.size()); System.out.println("是否已满:"+queue.isEmpty()); }
链式队列:
package test; import java.io.Serializable; public class LinkQueue<T> { // 定义一个内部类Node,Node实例代表链队列的节点。 private class Node { private T data;// 保存节点的数据 private Node next;// 指向下个节点的引用 // 无参数的构造器 public Node() { } // 初始化全部属性的构造器 public Node(T data, Node next) { this.data = data; this.next = next; } } private Node front;// 保存该链队列的头节点 private Node rear;// 保存该链队列的尾节点 private int size;// 保存该链队列中已包含的节点数 public LinkQueue() {// 空链队列,front和rear都是null front = null; rear = null; } public LinkQueue(T element) {// 只有一个节点,front、rear都指向该节点 front = new Node(element, null); rear = front; size++; } public int size() { return size; } public void insert(T element) {// 如果该链队列还是空链队列 if (front == null) { front = new Node(element, null); rear = front;// 只有一个节点,front、rear都指向该节点 } else { Node newNode = new Node(element, null);// 创建新节点 rear.next = newNode;// 让尾节点的next指向新增的节点 rear = newNode;// 以新节点作为新的尾节点 } size++; } public T remove() {// 出对 Node oldFront = front; front = front.next; oldFront.next = null; size--; return oldFront.data; } public T peek() {// 返回队列顶元素,但不删除队列顶元素 return rear.data; } public boolean isEmpty() {// 判断顺序队列是否为空队列 return size == 0; } public void clear() {// 清空顺序队列 // 将front、rear两个节点赋为null front = null; rear = null; size = 0; } public String toString() { // 链队列为空链队列时 if (isEmpty()) { return "[]"; } else { StringBuilder sb = new StringBuilder("["); for (Node current = front; current != null; current = current.next) { sb.append(current.data.toString() + ", "); } int len = sb.length(); return sb.delete(len - 2, len).append("]").toString(); } } }
测试:
@Test public void fun2() { LinkQueue lq = new LinkQueue(); lq.insert("sds"); lq.insert("sdfsa"); Integer in = 3; lq.insert(in); lq.insert("我"); System.out.println("插入的数据:"+lq.toString()); System.out.println("删除的数为:"+lq.remove()); }
将值大小作为优先级,实现优先队列:
package test; public class PriorityQueue { // 数组 private long[] arr; // 最大空间 private int maxSize; // 有效元素大小 private int elems; public PriorityQueue(int maxSize) { this.maxSize = maxSize; arr = new long[maxSize]; elems = 0; } // 插入数据 public void insert(long value) { int i; for (i = 0; i < elems; i++) { if(value < arr[i]) { break; } } for(int j = elems; j > i;j--){ arr[j] = arr[j - 1]; } arr[i] = value; elems++; } // 移除数据 public long remove() { long value = arr[elems - 1]; elems--; return value; } // 是否为空 public boolean isEmpty() { return (elems == 0); } // 是否满了 public boolean isFull() { return (elems == maxSize); } // 返回有效元素大小 public int size() { return elems; } }
测试:
@Test public void fun() { PriorityQueue pq = new PriorityQueue(10); pq.insert(30); pq.insert(45); pq.insert(15); pq.insert(2); pq.insert(1); while (!pq.isEmpty()) { long value = pq.remove(); System.out.print(value + " "); } }