zoukankan      html  css  js  c++  java
  • 数据结构与算法之队列

      队列中典型的就是遵循先进先出原则的,队列是操作受限制的线性表结构。

     一、队列的特点

    队列最大的特点就是先进先出,主要有两个操作入列和出列。
    跟栈一样,既可以用数组实现,又可以用链表实现,用数组实现叫顺序队列,用链表实现,叫链式队列,特别是一个长的像环的循环队列。
    在数组实现队列的时候,会有数据搬移操作,要想解决数据搬移的问题,我们就需要像环一样的循环队列。

    二、基于数组实现的队列

     1 public class ArrayQueue {
     2 
     3     // 数组:items 数组的大小:n
     4     private String[] items;
     5 
     6     private int n = 0;
     7 
     8     // head表示对头下标 tail表示队尾下标
     9     private int head = 0;
    10 
    11     private int tail = 0;
    12 
    13     /**
    14      * 申请一个大小为capacity的数组
    15      * 
    16      * @param capacity
    17      */
    18     public ArrayQueue(int capacity) {
    19         this.items = new String[capacity];
    20         this.n = capacity;
    21     }
    22 
    23     /**
    24      * 入列操作
    25      * 
    26      * @param item
    27      * @return
    28      */
    29     public boolean enqueue(String item) {
    30         // 如果tail == n 表示队列满了
    31         if (tail == n) {
    32             return false;
    33         }
    34         this.items[tail] = item;
    35         ++tail;
    36         return true;
    37     }
    38 
    39     /**
    40      * 出列操作
    41      * 
    42      * @return
    43      */
    44     public String dequeue() {
    45         // 如果 head == tail 表示队列为空
    46         if (this.head == this.tail) {
    47             return null;
    48         }
    49         String ret = this.items[head];
    50         ++head;
    51         return ret;
    52     }
    53 
    54     /**
    55      * 随着不停的入列,出列操作,当tail移动到最后一个数组位置的时候,即使数组中前面还有空余空间也无法在队列中添加数据了,解决这个问题的
    56      * 办法是进行数据搬移,将队列后面的数据搬移到前面空余的位置中,改造入队操作,若空间不足,触发数据搬移
    57      * 
    58      */
    59 
    60     /**
    61      * 改造之后的入列操作
    62      * 
    63      * @param item
    64      * @return
    65      */
    66     public boolean enqueue2(String item) {
    67         // tail == n 表示队列中没有剩余空间了
    68         if (tail == n) {
    69             // tail == n && head == 0表示整个队列都占满了
    70             if (head == 0) {
    71                 return false;
    72             }
    73             // 数据搬移
    74             for (int i = head; head < tail; ++i) {
    75                 this.items[i - head] = this.items[i];
    76             }
    77             // 搬移之后重新更新 head tail 向前移动了head距离
    78             tail -= head;
    79             head = 0;
    80         }
    81         this.items[tail] = item;
    82         ++tail;
    83         return true;
    84     }
    85 
    86 }

    三、基于链表实现的队列

     1 public class QueueBasedOnLinkedList {
     2 
     3     //队列的队首 和 队尾
     4     private Node head = null;
     5     private Node tail = null;
     6     
     7     /**
     8      * 入列操作
     9      * 
    10      * @param value
    11      */
    12     public void enqueue(String value){
    13         if(tail == null){
    14             Node newNode = new Node(value, null);
    15             head = newNode;
    16             tail = newNode;
    17         }else{
    18             tail = new Node(value, null);
    19             tail.next = tail;
    20         }
    21     }
    22     
    23     /**
    24      * 出列操作
    25      * 
    26      * @return
    27      */
    28     public String dequeue(){
    29         if(head == null){
    30             return null;
    31         }
    32         String value = head.data;
    33         head = head.next;
    34         if(head == null){
    35             tail = null;
    36         }
    37         return value;
    38     }
    39     
    40     public void printAll(Node node){
    41         while(node != null){
    42             System.out.print(node.data + " ");
    43             node = node.next;
    44         }
    45         System.out.println();
    46     }
    47     
    48     public static class Node{
    49         private String data;
    50         private Node next;
    51         
    52         public Node(String data, Node next){
    53             this.data = data;
    54             this.next = next;
    55         }
    56         
    57         public String getData(){
    58             return this.data;
    59         }
    60     }
    61 }

    四、环形队列

     1 public class CircularQueue {
     2 
     3     // 数组:items 数组长度:n
     4     private String[] items;
     5     private int n = 0;
     6 
     7     // head 表示对头下标 tail表示队尾下标
     8     private int head = 0;
     9     private int tail = 0;
    10 
    11     /**
    12      * 申请一个大小为capacity 的数组
    13      * 
    14      * @param capacity
    15      */
    16     public CircularQueue(int capacity) {
    17         this.items = new String[capacity];
    18         this.n = capacity;
    19     }
    20 
    21     /**
    22      * 入列操作
    23      * 
    24      * @return
    25      */
    26     public boolean enqueue(String item) {
    27         // 队列满了
    28         if ((tail + 1) % n == head) {
    29             return false;
    30         }
    31         this.items[tail] = item;
    32         tail = (tail + 1) % n;
    33         return true;
    34     }
    35 
    36     /**
    37      * 出列操作
    38      * 
    39      * @return
    40      */
    41     public String dequeue() {
    42         // 如果head = tail 表示队列为空
    43         if (head == tail) {
    44             return null;
    45         }
    46         String ret = items[head];
    47         head = (head + 1) % n;
    48         return ret;
    49     }
    50     
    51 }

    此大部分内容来自极客时间专栏,王争老师的《数据结构与算法之美》

    极客时间:https://time.geekbang.org/column/intro/126

  • 相关阅读:
    「板子」环形带限制的子段和
    【模版】拓扑排序
    【模板】点分治
    扬声大笑出门去,我辈岂是蓬蒿人
    JAVA JDK(3)—— jdk7特性
    电路原理 —— 三相电路(1.5)
    JAVA JDK(2)—— jdk6特性
    数据结构 —— 栈和队列
    电路原理(六) —— 正弦稳态电路分析(1)
    静电场(完) —— 静电场的环路定理 电势
  • 原文地址:https://www.cnblogs.com/ssh-html/p/10503549.html
Copyright © 2011-2022 走看看