顺序队列,循环队列,链队列

先看队列接口和结点类

package com.lovely.queue;

/** 
 * 2020年4月26日下午2:42:44
 * 
 * @author echo lovely
 *
 */
public interface IQueue {

	public void clear(); // 将队列置空
	public boolean isEmpty(); // 判断队列是否为空
	public int length(); // 返回队列的数据元素个数
	public Object peek(); // 返回队首元素 
	public void offer(Object x) throws Exception; // x插入队列,队尾入队
	public Object poll(); // 返回队首元素,并删除 队首出队
	public void display(); // 输出队列中所有数据元素
	
}

package com.lovely.linearList;

/** 
 * 2020年4月1日下午8:25:10
 * 
 * @author echo lovely
 *
 * @category 节点类 用于存数据 和 后继节点
 */

public class Node {
	public Object data; // 存放节点数据值
	public Node next; // 存放后继节点
	
	public Node() {
		this(null, null);
	}
	
	// 只有节点值的构造函数
	public Node(Object data) {
		this(data, null);
	}
	
	// 带有节点值和后继节点的构造函数
	public Node(Object data, Node next) {
		this.data = data;
		this.next = next;
	}
}

1. 顺序队列

package com.lovely.queue;

/**
 * @author echo lovely
 *
 * 2020年4月26日下午3:03:05
 * 
 * 队列的顺序储存结构
 * 队首出队(删除),队尾入队(插入)。
 */
public class SeqQueue implements IQueue {
	
	private Object[] queueElem; // 队列的储存空间
	private int maxSize; // 队列的最大储存单元个数
	private int front; // 指向队首元素
	private int rear; // 指向队尾元素的下一个元素	

	// 构造最大储存单元为maxSize的空队列
	public SeqQueue(int maxSize) {
		this.maxSize = maxSize;
		front = rear = 0;
		queueElem = new Object[maxSize];
	}
	
	@Override
	public void clear() {
		// 队列置空
		front = rear = 0;	
	}

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

	@Override
	public int length() {
		// 队列长度
		return rear - front;
	}

	@Override
	public Object peek() {
		// 返回队首元素
		if (isEmpty())
			return null;
		return queueElem[front];
	}

	@Override
	public void offer(Object x) throws Exception {
		// 队尾入队
		if (rear == maxSize)
			throw new Exception("队列已满");
		queueElem[rear] = x;
		rear ++; // 指向队尾的下一个元素
	}

	@Override
	public Object poll() {
		// 出队 只不过是不显示罢了
		if (isEmpty())
			return null;
		front ++; // 指向原来队首元素的下一个元素
		return queueElem[front];
	}

	@Override
	public void display() {
		if (!isEmpty()) {
			for (int i = front; i < rear; i++) {
				System.out.print(queueElem[i] + "\t");
			}
		} else
			System.out.println("队列为空!");
		
	}

}

  • 测试
package com.lovely.queue;

public class TestSeqQueue {

	public static void main(String[] args) {
		// 顺序队列
		SeqQueue sq = new SeqQueue(6);
		try {
			// 入队
			sq.offer(1);
			sq.offer(2);
			sq.offer(3);
			sq.offer(4);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("队列长度 " + sq.length());
		Object obj = sq.poll();
		System.out.println(obj + "出队后,长度 " + sq.length());
		System.out.println("队首元素:" + sq.peek());
		sq.display();
		
		
/*		
	这里有问题,多次入队出队操作,造成有存储空间却不能进行入队操作的"假溢出"现象
	try {
			sq.offer(88);
			sq.offer(88);
			sq.poll();
			sq.poll();
			sq.offer(88);
			sq.poll();
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("\n长度 " + sq.length());
		sq.display();*/

/*
队列长度 4
2出队后,长度 3
队首元素:2
2	3	4
*/
	}

}

2. 循环队列

package com.lovely.queue;

/**
 * 
 * @author echo lovely
 *
 * 2020年5月19日下午8:53:03
 * 
 * 循环顺序队列
 * 顺序队列的多次入队和出队 会造成有储存空间 却不能进行入队操作的假溢出现象。
 */
public class CircleSeqQueue {
	private Object[] queueElem; // 队列的储存空间
	private int front; // 指向队首元素
	private int rear; // 指向队尾元素的下一个储存元素
	private int maxSize; // 队列的最大储存单元个数
	
	// 构造最大储存单位个数为maxSize的空队列
	public CircleSeqQueue(int maxSize) {
		front = rear = 0;
		queueElem = new Object[maxSize];
		this.maxSize = maxSize;
	}
	
	// 将队列置空
	public void clear() {
		front = rear = 0;
	}
	
	// 判断队列是否为空
	public boolean isEmpty() {
		return front == rear;
	}
	
	// 队列的长度
	public int length() {
		return (rear - front + maxSize) % maxSize; 
	}
	
	// 读取队首元素
	public Object peek() {
		if (isEmpty())
			return null;
		return queueElem[front];
	}
	
	// 入队
	public void offer(Object x) throws Exception {
		if ((rear + 1) % maxSize == front) 
			throw new Exception("队列已满");
		queueElem[rear] = x;
		rear = (rear + 1) % maxSize;
	}
	
	// 出队
	public Object poll() {
		if (rear == front)
			return null;
		Object p = queueElem[front];
		front = (front + 1) % maxSize;
		return p;
	}
	
	// 遍历队列
	public void display() {
		if (!isEmpty()) {
			for (int i = 0; i < rear; i = (i + 1) % maxSize) {
				System.out.print(queueElem[i] + " ");
			}
		} else
			System.out.println("此队列为空!");
	}
}

  • 测试
package com.lovely.queue;

public class TestCircleSeqQueue {

	public static void main(String[] args) {
		
		// 构造长度为10的队列
		CircleSeqQueue csq = new CircleSeqQueue(10);
		try {
			csq.offer(1);
			csq.offer(2);
			csq.offer(3);
			csq.offer(4);
			csq.offer(5);
			csq.offer(6);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		System.out.println("队首元素:" + csq.peek());
		
		System.out.println("出队:" + csq.poll());
		
		csq.display();

	}

}

/**
队首元素:1
出队:1
2 3 4 5 6 
*/

3. 链队列

package com.lovely.queue;

import com.lovely.linearList.Node;

/**
 * 
 * @author echo lovely
 * 2020年6月7日下午7:20:02
 * 
 * 链队列 
 * 使用单链表实现
 * 实现入队队尾 出队队首, 没有中间的插入或者删除
 * 
 * 无需头节点 , front指向头节点 rear指向队尾结点便可
 */
public class LinkQueue implements IQueue {
	
	private Node front; // 队首指针
	private Node rear; // 队尾指针
	
	// 构造空队列
	public LinkQueue() {
		front = rear = null;
	}

	public void clear() {
		front = rear = null;
	}

	public boolean isEmpty() {
		// 队首是否为空
		return front == null;
	}

	@Override
	public int length() {
		Node p = front;
		int length = 0;
		while (p != null) {
			p = p.next;
			length ++;
		}
		return length;
	}

	// 返回队首元素值
	public Object peek() {
		if (isEmpty()) 
			return null;
		return front.data;
	}

	@Override
	public void offer(Object x) throws Exception {
		// 入队
		Node s = new Node(x);
		
		if (!isEmpty()) { // 队列非空
			rear.next = s;
			rear = s;
		} else 
			front = rear = s;
	}

	// 出队
	public Object poll() {
		if (front == null)
			return null;
		Node p = front;
		front = front.next;
		
		if (p == rear) {
			rear = null; // 删除结点为队尾结点时需要修改rear
		}
		
		return p.data;
	}

	public void display() {
		if (!isEmpty()) {
			for(Node p = front;p != null;p = p.next) {
				System.out.print(p.data + "\t");
			}
			System.out.println();
		} else {
			System.out.println("此队列为空");
		}
		
	}

}

  • 测试
package com.lovely.queue;

public class TestLinkQueue {

	public static void main(String[] args) {
		// 链队列的增删改查
		LinkQueue lq = new LinkQueue();
		try {
			lq.offer(2);
			lq.offer(3);
			lq.offer(5);
			lq.offer(7);
			lq.offer(11);
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("入队的队列:");
		lq.display();

		System.out.println("队首元素:" + lq.peek());
		
		System.out.println("队首出队:" + lq.poll());
		
		lq.display();
		
		System.out.println("队列的长度为:" + lq.length());
	}

}

/**
入队的队列:
2	3	5	7	11	
队首元素:2
队首出队:2
3	5	7	11	
队列的长度为:4

*/

猜你喜欢

转载自blog.csdn.net/qq_44783283/article/details/106606647