算法新手模块学习之单链表实现队列,栈 双链表实现双端队列

单链表实现队列,栈

首先定义一个单链表Node

    static class Node<V> {
        Node next;
        V value;

        public Node(V value) {
            this.value = value;
        }
    }

单链表实现队列,遵循先进先出,后进后出
简单画图说一下解法思路,这里拿inPutTail方法为例(我觉得链表问题画画图就好理解好多了)
第一次插入的时候,因为是从尾巴插入的,所以判断尾巴为空的话就将head和tail指向当前值node(图中的圆圈就是当前值node)
在这里插入图片描述
第二次插入的时候,尾巴不为空,所以将尾巴的下一个节点指向当前值node,尾巴指向当前值
在这里插入图片描述
也就是在这里插入图片描述
以此类推

 static class MyQueue<V> {
     Node<V> head;
     Node<V> tail;
     int size ;

     public MyQueue() {
         head = null;
         tail = null;
         size = 0;
     }

     public void inPutTail(V value) {
         Node node = new Node(value);
         if (tail == null) {
             head = node;
             tail = node;
         } else {
             tail.next = node;
             tail = node;
         }
         size++;
     }

     public V outPutHead() {
         if (head==null){
             return null;
         }
         V value = head.value;
         head = head.next;
         size--;
         if (head==null){
             tail =null;
         }
         return value;
     }

     public V peekHead() {
         if (head==null){
             return null;
         }
         V value = head.value;
         return value;
     }

     public Integer getSize() {
         return size;
     }

     public boolean isEmpty() {
         return size == 0;
     }

 }

单链表实现栈,遵循先进后出,后进先出
inPutHead方法为例
第一次插入的时候,因为是从头插入的,所以判断头为空的话就将head指向当前值node
在这里插入图片描述
第二次插入的时候,头不为空,当前值的下一个节点指向老头,老头指向当前值成为新头
在这里插入图片描述
也就是
在这里插入图片描述
以此类推

   static class Mystack<V>{
       Node<V> head ;
       int size;

       public Mystack() {
           head = null;
           size = 0 ;
       }

       public void inPutHead(V value){
           Node<V> node = new Node<>(value);
           if (head==null){
               head = node;
           }else {
               node.next = head;
               head = node;
           }
           size++;
       }
       public V outPutHead(){
           if (head==null){
               return null;
           }
           V value = head.value;
           head = head.next;
           size--;
           return value;
       }
       public V peekHead(){
           return head == null?null:head.value;
       }
       public Integer getSize() {
           return size;
       }

       public boolean isEmpty() {
           return size == 0;
       }
   }

写个对数器来检验写的队列和栈是否正确,其实就是利用queue队列和随机数检验

 public static void testQueue() {
     MyQueue<Integer> myQueue = new MyQueue<>();
     Queue<Integer> test = new LinkedList<>();
     int testTime = 5000000;
     int maxValue = 200000000;
     System.out.println("开始!");
     for (int i = 0; i < testTime; i++) {
         if (myQueue.isEmpty() != test.isEmpty()) {
             System.out.println("错了1!");
         }
         if (myQueue.getSize() != test.size()) {
             System.out.println("错了2!");
         }
         double decide = Math.random();
         if (decide < 0.33) {
             int num = (int) (Math.random() * maxValue);
             myQueue.inPutTail(num);
             test.offer(num);
         } else if (decide < 0.66) {
             if (!myQueue.isEmpty()) {
                 int num1 = myQueue.outPutHead();
                 int num2 = test.poll();
                 if (num1 != num2) {
                     System.out.println("错了3!");
                 }
             }
         } else {
             if (!myQueue.isEmpty()) {
                 int num1 = myQueue.peekHead();
                 int num2 = test.peek();
                 if (num1 != num2) {
                     System.out.println("错了4!");
                 }
             }
         }
     }
     if (myQueue.getSize() != test.size()) {
         System.out.println("错了5!");
     }
     while (!myQueue.isEmpty()) {
         int num1 = myQueue.outPutHead();
         int num2 = test.poll();
         if (num1 != num2) {
             System.out.println("错了6!");
         }
     }
     System.out.println("结束!");
 }

 public static void testStack() {
     Mystack<Integer> myStack = new Mystack<>();
     Stack<Integer> test = new Stack<>();
     int testTime = 5000000;
     int maxValue = 200000000;
     System.out.println("开始!");
     for (int i = 0; i < testTime; i++) {
         if (myStack.isEmpty() != test.isEmpty()) {
             System.out.println("错了1!");
         }
         if (myStack.getSize()!= test.size()) {
             System.out.println("错了2!");
         }
         double decide = Math.random();
         if (decide < 0.33) {
             int num = (int) (Math.random() * maxValue);
             myStack.inPutHead(num);
             test.push(num);
         } else if (decide < 0.66) {
             if (!myStack.isEmpty()) {
                 int num1 = myStack.outPutHead();
                 int num2 = test.pop();
                 if (num1 != num2) {
                     System.out.println("错了3!");
                 }
             }
         } else {
             if (!myStack.isEmpty()) {
                 int num1 = myStack.peekHead();
                 int num2 = test.peek();
                 if (num1 != num2) {
                     System.out.println("错了4!");
                 }
             }
         }
     }
     if (myStack.getSize() != test.size()) {
         System.out.println("错了5!");
     }
     while (!myStack.isEmpty()) {
         int num1 = myStack.outPutHead();
         int num2 = test.pop();
         if (num1 != num2) {
             System.out.println("错了6!");
         }
     }
     System.out.println("结束!");
 }

双链表实现双端队列
首先定义一个双链表

static class Node<V> {
       Node next;
       Node last;
       V value;

       public Node(V value) {
           this.value = value;
       }
   }

双链表实现双端队列,实现弹出头,弹出尾,插入头,插入尾等
这里拿inPutHead画图简单解释一下
第一次插入头,头尾都指向当前值node
在这里插入图片描述
第二次插入头,老头的上一节点指向当前值,当前值的下一节点指向老头,老头指向当前值成为新头
在这里插入图片描述

在这里插入图片描述
以此类推

 static class MyDequeue<V> {
        Node<V> head;
        Node<V> tail;
        int size;

        public MyDequeue() {
            head = null;
            tail = null;
            size = 0;
        }

        public void inPutHead(V value) {
            Node<V> node = new Node<>(value);
            if (head == null) {
                head = node;
                tail = node;
            } else {
                head.last = node;
                node.next = head;
                head = node;
            }
            size++;
        }

        public void inPutTail(V value) {
            Node<V> node = new Node<>(value);
            if (tail == null) {
                tail = node;
                head = node;
            } else {
                tail.next = node;
                node.last = tail;
                tail = node;
            }
            size++;
        }

        public V outPutHead() {
            if (head == null) {
                return null;
            }
            V ans = head.value;
            if (head.next != null) {
                head = head.next;
                head.last = null;

            } else {
                head = tail = null;
            }
            size--;
            return ans;
        }

        public V outPutTail() {
            if (tail == null) {
                return null;
            }
            V ans = tail.value;
            if (tail.last != null) {
                tail = tail.last;
                tail.next = null;

            } else {
                head = tail = null;
            }
            size--;
            return ans;
        }

        public V peekHead() {
            V ans = null;
            if (head != null) {
                ans = head.value;
            }
            return ans;
        }

        public V peekTail() {
            V ans = null;
            if (tail != null) {
                ans = tail.value;
            }
            return ans;
        }

        public Integer getSize() {
            return size;
        }

        public boolean isEmpty() {
            return size == 0;
        }

    }

对数器检验是否正确,其实就是利用deque双端队列和随机数检验

 public static void testDeque() {
        MyDequeue<Integer> myDeque = new MyDequeue<>();
        Deque<Integer> test = new LinkedList<>();
        int testTime = 5000000;
        int maxValue = 200000000;
        System.out.println("开始!");
        for (int i = 0; i < testTime; i++) {
            if (myDeque.isEmpty() != test.isEmpty()) {
                System.out.println("错了1!");
            }
            if (myDeque.getSize() != test.size()) {
                System.out.println("错了2!");
            }
            double decide = Math.random();
            if (decide < 0.33) {
                int num = (int) (Math.random() * maxValue);
                if (Math.random() < 0.5) {
                    myDeque.inPutHead(num);
                    test.addFirst(num);
                } else {
                    myDeque.inPutTail(num);
                    test.addLast(num);
                }
            } else if (decide < 0.66) {
                if (!myDeque.isEmpty()) {
                    int num1 = 0;
                    int num2 = 0;
                    if (Math.random() < 0.5) {
                        num1 = myDeque.outPutHead();
                        num2 = test.pollFirst();
                    } else {
                        num1 = myDeque.outPutTail();
                        num2 = test.pollLast();
                    }
                    if (num1 != num2) {
                        System.out.println("错了3!");
                    }
                }
            } else {
                if (!myDeque.isEmpty()) {
                    int num1 = 0;
                    int num2 = 0;
                    if (Math.random() < 0.5) {
                        num1 = myDeque.peekHead();
                        num2 = test.peekFirst();
                    } else {
                        num1 = myDeque.peekTail();
                        num2 = test.peekLast();
                    }
                    if (num1 != num2) {
                        System.out.println("错了4!");
                    }
                }
            }
        }
        if (myDeque.getSize() != test.size()) {
            System.out.println("错了5!");
        }
        while (!myDeque.isEmpty()) {
            int num1 = myDeque.outPutHead();
            int num2 = test.pollFirst();
            if (num1 != num2) {
                System.out.println("错了6!");
            }
        }
        System.out.println("结束!");
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/* * 基于双向链表实现双端队列结构 */ package dsa; public class Deque_DLNode implements Deque { protected DLNode header;//指向头节点(哨兵) protected DLNode trailer;//指向尾节点(哨兵) protected int size;//队列中元素的数目 //构造函数 public Deque_DLNode() { header = new DLNode(); trailer = new DLNode(); header.setNext(trailer); trailer.setPrev(header); size = 0; } //返回队列中元素数目 public int getSize() { return size; } //判断队列是否为空 public boolean isEmpty() { return (0 == size) ? true : false; } //取首元素(但不删除) public Object first() throws ExceptionQueueEmpty { if (isEmpty()) throw new ExceptionQueueEmpty("意外:双端队列为空"); return header.getNext().getElem(); } //取末元素(但不删除) public Object last() throws ExceptionQueueEmpty { if (isEmpty()) throw new ExceptionQueueEmpty("意外:双端队列为空"); return trailer.getPrev().getElem(); } //在队列前端插入新节点 public void insertFirst(Object obj) { DLNode second = header.getNext(); DLNode first = new DLNode(obj, header, second); second.setPrev(first); header.setNext(first); size++; } //在队列后端插入新节点 public void insertLast(Object obj) { DLNode second = trailer.getPrev(); DLNode first = new DLNode(obj, second, trailer); second.setNext(first); trailer.setPrev(first); size++; } //删除首节点 public Object removeFirst() throws ExceptionQueueEmpty { if (isEmpty()) throw new ExceptionQueueEmpty("意外:双端队列为空"); DLNode first = header.getNext(); DLNode second = first.getNext(); Object obj = first.getElem(); header.setNext(second); second.setPrev(header); size--; return(obj); } //删除末节点 public Object removeLast() throws ExceptionQueueEmpty { if (isEmpty()) throw new ExceptionQueueEmpty("意外:双端队列为空"); DLNode first = trailer.getPrev(); DLNode second = first.getPrev(); Object obj = first.getElem(); trailer.setPrev(second); second.setNext(trailer); size--; return(obj); } //遍历 public void Traversal() { DLNode p = header.getNext(); while (p != trailer) { System.out.print(p.getElem()+" "); p = p.getNex

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值