数据结构循环顺序队列、链队和优先级队列的Java实现

本篇博文用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(地址在文章开头)或我的其他博文,感觉不错的话,关注一下吧!

发布了34 篇原创文章 · 获赞 65 · 访问量 3737

猜你喜欢

转载自blog.csdn.net/baidu_41860619/article/details/103540763