本篇博文用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(地址在文章開頭)或我的其他博文,感覺不錯的話,關注一下吧!