本篇博文用java实现了数据结构中的循环顺序队列、链队和优先级队列
源码分享在github:数据结构,当然你也可以从下面的代码片中获取
1.队列接口 IQueue .java
/*
* 队列接口
* */
public interface IQueue {
public void clear();//清空队列
public boolean isEmpty();//判空
public int length();//返回队列元素长度
public Object peek();//读取队首元素
public void offer(Object x)throws Exception;//入队
public Object poll();//出队
}
2.循环顺序队列 CircleSqQueue.java
/*
* 循环顺序队列
* 解决假溢出问题
* */
public class CircleSqQueue implements IQueue {
private Object[] queueElem;//队列存储空间
private int front;//队首的引用,若队列不空,指向队首元素
private int rear;//队尾的引用,若队列不空,指向队尾的下一个存储位置
//循环队列类的构造函数
public CircleSqQueue(int 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+queueElem.length)%queueElem.length;//rear-front有可能是负数,则需要+queueElem.length
}
//读取队首的元素
@Override
public Object peek() {
if(front == rear){
return null;
}else{
return queueElem[front];
}
}
//入队
@Override
public void offer(Object x) throws Exception {
if((rear+1)%queueElem.length==front){ //判断队列是否满了,此时故意少存储一位
throw new Exception("队列已满");
}else{
queueElem[rear] = x;
}
rear = (rear+1)%queueElem.length;
}
//出队
@Override
public Object poll() {
if(front == rear)
return null;
else{
Object t = queueElem[front];
front = (front+1)%queueElem.length;
return t;
}
}
//输出
public void display(){
if(!isEmpty()){
for(int i = front;i!=rear;i = (i+1)%queueElem.length)
System.out.print(queueElem[i].toString()+" ");
}else{
System.out.println("此队列为空");
}
}
}
3.链队 LinkQueue.java
public class LinkQueue implements IQueue {
private Node front;//队首指针
private Node rear;//队尾指针
//构造函数
public LinkQueue() {
front = rear = null;
}
//队列置空
@Override
public void clear() {
front = rear = null;
}
//判空
@Override
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;
}
//取队首元素
@Override
public Object peek() {
if(front!=null)
return front.data;
else
return null;
}
//入队
@Override
public void offer(Object x) throws Exception {
Node p = new Node(x);
if(front!=null){
rear.next = p;
rear = p;
}else{
front = rear = p;
}
}
//出队
@Override
public Object poll() {
if(front!=null){
Node p = front;
front = front.next;//队首节点出列
if(p==rear) //被删除的节点是队尾节点时候
rear=null;
return p.data;
}else
return null;
}
}
其中,Node.java 节点类:
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;
}
}
4.优先级队列
4.1 节点中data类 PriorityQData.java
/*
* 优先级队列
* 一种带有优先级的队列
* 约定关键字最小的数据元素具有最高优先级,并且排在队首
* 优先级队列中的数据元素插入也不仅仅限制在队尾进行,而是顺序插入到队列的 合适位置,以确保队列的优先级顺序
*
*
* 此类为优先级队列的节点中data类的描述
* */
public class PriorityQData {
public Object elem; //节点类的数据元素值
public int priority;//节点类的优先数
//构造函数
public PriorityQData() {
this.elem = elem;
this.priority = priority;
}
public Object getElem() {
return elem;
}
public void setElem(Object elem) {
this.elem = elem;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
}
4.2 节点类 Node.java
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;
}
}
4.3 优先级队列 PriorityQueue.java
public class PriorityQueue implements IQueue {
private Node front;//队首的引用
private Node rear;//队尾的引用
//构造函数
public PriorityQueue() {
front = rear = null;
}
//队列置空
@Override
public void clear() {
front = rear = null;
}
//队列判空
@Override
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;
}
//读取队首元素
@Override
public Object peek() {
if(front == null)
return null;
else
return front.data;
}
//入队
@Override
public void offer(Object x) throws Exception {
PriorityQData pn = (PriorityQData)x;
Node s = new Node(pn); //构造一个新节点
if(front == null) //队列为空
front = rear = s;//修改队列的首位节点
else{
Node p = front,q = front;
//新结点的数据域值与队列节点的数据域值相比较
while(p!=null&&pn.priority>=((PriorityQData)p.data).priority){
q = p;
p = p.next;
}
if(p == null){ //p为空,表示遍历到了队列尾部
rear.next = s;//将新节点加入到队尾
rear = s;//修改队尾指针
}else if(p == front){//p的优先级大于队首节点的优先级
s.next = front;//将新结点加入到队首
front = s;//修改队首节点
}else{ //新结点加入队列中部
q.next = s;
s.next = p;
}
}
}
//出队
@Override
public Object poll() {
if(front == null)
return null;
else{
Node p = front;
front = p.next;
return p.data;
}
}
//输出
public void display(){
if(!isEmpty()){
Node p = front;
while(p!=rear.next){
PriorityQData q = (PriorityQData)p.data;
System.out.println(q.elem+" "+q.priority);
p = p.next;
}
}else{
System.out.println("此队列为空");
}
}
}
数据结构这个系列是我学习时做的笔记,会持续更新,详见我的github(地址在文章开头)或我的其他博文,感觉不错的话,关注一下吧!