队列-用非顺序映像实现队列

(一).队列的理解

  (1)概述:和栈相反,队列是一种先进先出的线性表(FIFO),它只允许在表的一端进行插入,而在另一端删除元素,允许掺入的一端在表尾,我们通常称之为队尾,允许删除的一端为表头,我们通常称之为队头。

                

  (2)队列的非顺序映像:指的是以链表的形式来表示队列,我用的是单链表实现的。

    a.入队:

      相当于插入操作,只不过插入的位置固定在队尾。

    b.出队:

      相当于删除操作,不过删除的位置固定在队头。

(二)代码实现

  (1)先定义一个Queue接口

public interface Queue<T> {

    //获取队列大小
    public  int size();

    //返回栈顶元素,但不删除栈顶元素
    public T peek();

    //入队
    public void offer(T s);

    //出队
    public T poll();

    //清空队
    public void clear();

    //判断队空
    public boolean isEmpty();
}
interface Queue
(2)然后定义一个LinkedQueue类实现Queue接口
public class LinkedQueue<T> implements Queue<T> {
    private Node front;//头节点
    private Node rear;//尾节点
    private int size;//队列中节点的个数

    //定义一个内部类Node
    private class Node{
        private T data;
        private Node next;

        public Node() {
            super();
        }

        public Node(T data, Node next) {
            this.data = data;
            this.next = next;
        }
    }

    ///////////////////////// 下面是队列的各项功能 //////////////////////
    /**
     * 获取队列中保存的节点个数
     * @return 队列中保存的节点个数
     */
    @Override
    public int size() {
        return size;
    }

    /**
     * 获取队头节点,但是不删除队头节点
     * @return 获取的队头节点
     */
    @Override
    public T peek() {
        if(isEmpty()){
            throw new NoSuchElementException("队为空!");
        }
        return front.data;
    }

    /**
     * 入队
     * @param s 要入队的元素
     */
    @Override
    public void offer(T s) {
        //如果队还是空队列
        if(front == null){
            front = new Node(s, null);
            rear = front;//将插入的节点作为尾节点
        }else {
            Node nodeForAdd = new Node(s,null);
            rear.next = nodeForAdd;//让尾节点的next指向新节点
            rear = nodeForAdd;//插入的新节点成为尾节点
        }
        size++;
    }

    /**
     * 出队
     * @return 出队的元素
     */
    @Override
    public T poll() {
        if(isEmpty()){
            throw new NoSuchElementException("队为空!");
        }else {
            Node oldFront = front;
            front = front.next;//让头节点的下一个节点成为新的头节点
            oldFront.next = null;//让原来的头节点成为垃圾,等待被回收
            size--;
            return oldFront.data;
        }
    }

    /**
     * 清空队列
     */
    @Override
    public void clear() {
        front = null;
        rear = null;
        size = 0;
    }

    /**
     * 判断队列是否为空
     * @return 如果队列为空,返回ture,否则返回false
     */
    @Override
    public boolean isEmpty() {
        return size == 0;
    }

    //遍历队列,按照先进先出(FIFO)的顺序
    @Override
    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();
       }
    }
}
LinkedQueue
(3)最后定义一个测试类
public static void main(String[] args) {
        LinkedQueue ss = new LinkedQueue();
//        System.out.println(ss.isEmpty());
//        System.out.println(ss.toString());
//        System.out.println(ss.size());

        //入队
        ss.offer("hello");
        ss.offer("world");
        ss.offer("java");
        System.out.println(ss.toString());
        System.out.println(ss.size());

        //获取队头元素
        System.out.println("队头元素为:" + ss.peek());

        //删除一个元素(出队)
        System.out.println("----------------------");
        ss.poll();
        System.out.println("删除一个元素后:" + ss.toString());
        System.out.println(ss.size());

        //清空队列
        System.out.println("----------------------");
        ss.clear();
        System.out.println("清空队列后:" + ss.toString());
        System.out.println(ss.size());
    }
main
(4)运行结果:


原文地址:https://www.cnblogs.com/bug-baba/p/10510027.html