java使用单链表模拟队列

队列简介:

在这里插入图片描述

在这里插入图片描述

队列入队出队原理图:

在这里插入图片描述

队列入队出队代码:

代码演示:

package com.fan.queue;

//此类用来模拟队列,我们
public class LinekdListAndQueue<E> {
    //根据队列的基本简介,需要有一个队头和队尾
    //1.设置节点内为内部类,是单链表节点
    private class Node<E> {
        //数据域,为了省略篇幅,没有用私有属性和set,get方法
        E e;
        //指针域
        Node next;

        public Node(E e) {
            this.e = e;
        }

        public Node(E e, Node next) {
            this.e = e;
            this.next = next;
        }

        @Override
        public String toString() {
            return "Node{" +
                    "e=" + e +
                    '}';
        }
    }
    //2.接下来写队列的队头和队尾,即头节点和尾节点
    private Node<E> headNode ;//此指针一直指向队头
    private Node<E> tailNode;//此指针一直指向队尾
    private int size;//size = 0;

    public LinekdListAndQueue() {//构造方法
        //构造一个空链表的时候,没有队头和队尾节点,所以让其明显指向null
        headNode = null;
        tailNode = null;
    }
    //入队操作offer,e为要入队的元素
    public boolean offer(E e){
        //将元素封装成新节点
        Node<E> newNode = new Node<E>(e);
        //1.第一次入空队,判断是否为空,为空要单独添加
        if(headNode == null){//如果头节点为空,即当前队列没有节点
            headNode = newNode;//让新节点称为队首,即头节点指向新节点
            tailNode = newNode;//此时队列中只有一个节点,既是队头也是队尾
        }else{//队列不为空,
            //将新添加的节点放到尾节点的后边
            tailNode.next = newNode;
            //现在末尾又增加新节点了,所以,尾节点指针要后移,重新指向最后的尾节点
            tailNode = newNode;
        }
        //如果返回值是boolean类型则这样写,即尾节点地址和新增加的节点地址是否相同
        return tailNode == newNode;
    }
    //出队操作
    public E pool(){
        //先判断队列是不是为空
        if(headNode == null){//如果头节点或者尾节点指向了nul,就证明队列为空
            return null;
        }
        //先将头节点的元素保存
        E v =  headNode.e;
        //然后就可以将当前头节点删除,即出队
        headNode = headNode.next;//头节点往后移,尾节点不动
        return v;//返回头节点
    }
    //显示队首元素
    public E peek(){
        if(headNode == null){
            return null;
        }
        E v = headNode.e;
        return v;
    }
    //获取队列元素个数
    public int getSize(){
        //定义一个临时节点curr用来遍历
        Node<E> curr = headNode;//从头开始遍历
        while(true){
            if(curr == null){
                break;
            }
            size++;
            curr = curr.next;//后移遍历
        }
        return size;
    }
    //链表的节点显示
    public void show(){
        //定义一个临时节点curr用来遍历
        Node<E> curr = headNode;//从头开始遍历
        while(true){
            if(curr == null){
                break;
            }
            System.out.println(curr);//打印节点
            curr = curr.next;//后移遍历
        }
    }
}

测试类:

package com.fan.queue;

public class LinekdListAndQueueTest {
    public static void main(String[] args) {
        LinekdListAndQueue<Integer> linekdListAndQueue
                = new LinekdListAndQueue<Integer>();
        System.out.println(linekdListAndQueue.offer(1));
        System.out.println(linekdListAndQueue.offer(2));
        System.out.println(linekdListAndQueue.offer(3));
        linekdListAndQueue.show();
        System.out.println("显示队首:"+linekdListAndQueue.peek());
        System.out.println("显示队元素个数:"+linekdListAndQueue.getSize());
        System.out.println("出队:"+linekdListAndQueue.pool());
        System.out.println("出队:"+linekdListAndQueue.pool());
        System.out.println("出队:"+linekdListAndQueue.pool());
        System.out.println("出队:"+linekdListAndQueue.pool());
    }
}

删除某个元素:

//删除某个节点
    public E remove(E key){//key为要删除的元素
       //因为单链表的删除要找到要删除节点的前一个节点,
        // 所以我么设置一个空数据的头节点
        Node<E> head = new Node<E>((E) Integer.valueOf(-1),null);
        head.next = headNode;//让head作为头节点的上一个节点
        Node<E> curr = head;//遍历的临时节点curr,并指向新的头节点
        boolean flag = false;//是否找到要删除的节点
        while(true){
            if(curr.next == null){
                break;//到链表末尾
            }
            if(curr.next.e == key){//找到了
                flag = true;
                break;
            }
            curr = curr.next;
        }
        if(flag){
            E v = (E) curr.next.e;
            curr.next = curr.next.next;
            //让头节点重新指向第一个有效元素,因为show方法是从headNode开始遍历的
            headNode = head.next;
            return v;
        }else{
            System.out.println("没找到要删除的元素--");
            return  null;
        }

    }

测试类:

package com.fan.queue;

public class LinekdListAndQueueTest {
    public static void main(String[] args) {
        LinekdListAndQueue<Integer> linekdListAndQueue
                = new LinekdListAndQueue<Integer>();
        System.out.println(linekdListAndQueue.offer(1));
        System.out.println(linekdListAndQueue.offer(2));
        System.out.println(linekdListAndQueue.offer(3));
        System.out.println(linekdListAndQueue.offer(4));
        linekdListAndQueue.show();
        System.out.println("显示队首:"+linekdListAndQueue.peek());
        System.out.println("显示队元素个数:"+linekdListAndQueue.getSize());
        System.out.println("删除元素:"+linekdListAndQueue.remove(8));
        System.out.println("删除后显示队列:");
        linekdListAndQueue.show();
        System.out.println(linekdListAndQueue.offer(5));
        linekdListAndQueue.show();
        System.out.println("出队:"+linekdListAndQueue.pool());
        System.out.println("出队:"+linekdListAndQueue.pool());
        System.out.println("出队:"+linekdListAndQueue.pool());
        System.out.println("出队:"+linekdListAndQueue.pool());
    }
}

测试结果:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值