4.[数据结构和算法分析笔记]队列 Queue

简介:

1.队列Queue

定义

队列又叫做FIFO(先进先出)表,即first-in,first-out

现实中的队列

——排队

131734283.png

队列的接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public  interface  QueueInterface<T> {
     /**
      * 将新元素插入队列后端
      * @param newEntry 待插入的对象 */
     public  void  enqueue(T newEntry);
     /**
      * 删除并返回队列前端对象
      * @return 位于队列前端的对象,如果队列为空则返回null */
     public  T dequeue();
     /**
      * 检索队列前端对象
      * @return 位于队列前端的对象,如果队列为空则返回null */
     public  T getFront();
     /**
      * 检查队列是否为空
      * @return 如果队列为空则返回true */
     public  boolean  isEmpty();
     /**
      * 从队列中删除所有元素 */
     public  void  clear();
}

Java类库:Queue接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public  interface  Queue<T> {
     // 在对象的末端插入一个新元素,如果插入成功则返回true,否则抛出一个异常
     public  boolean  add(T newEntry);
     // 在对象的末端插入一个新元素,根据此操作成功与否返回true或false
     public  boolean  offer(T newEntry);
     // 在队列的前端检索并删除元素,如果在此操作之前队列已为空,则抛出异常NoSuchElementException
     public  T remove();
     // 在队列的前对检索并删除元素,如果在此操作之前队列已为空,则返回null
     public  T poll();
     // 检索队列前端的元素,如果队列为空,则抛出异常NoSuchelementException
     public  T element();
     // 检索队列前端的元素,如果队列为空,则返回null
     public  T peek();
     // 检索队列是否为空
     public  boolean  isEmpty();
     // 删除队列的所有元素
     public  void  clear();
     // 获得当前队列中的元素数据
     public  int  size();
     // 返回作用于队列的元素的迭代期器
     public  Iterator<T> iterator();
}

双端队列接口描述

1
2
3
4
5
6
7
8
9
10
11
public  interface  DequeInterface<T> {
                                 
     public  void  addToFront(T newEntry);
     public  void  addToBack(T newEntry);
     public  T removeFront();
     public  T removeBack();
     public  T getFront();
     public  T getBack();
     public  boolean  isEmpty();
     public  void  clear();  
}

优先队列的接口描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public  interface  PriorityQueueInterface<T  extends  Comparable<?  super  T>> {
     /**
      * 将新元素插入优先队列
      * @param newEntry newEntry一个对象 */
     public  void  add(T newEntry);
     /**
      * 删除并返回优先队列最高的元素
      * @return 优先级最高的对象,如果优先队列为空则返回null */
     public  T remove();
     /**
      * 检索优先级最高的元素
      * @return 优先级最高的对象,如果优先队列为空则返回null */
     public  T peek();
     /**
      * 检索优先队列是否为空
      * @return 如果优先队列为空则返回true */
     public  boolean  isEmpty();
     /**
      * 缺德优先队列的长度
      * @return 当前优先队列中的元素数据 */
     public  int  getSize();
     /**
      * 从优先队列中删除所有元素 */
     public  void  clear();
}

2.基于(双端)链表的队列实现

131907724.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public  class  LinkedQueue<T>  implements  QueueInterface<T>, Serializable {
     private  Node firstNode;  // 引用队列前端的结点
     private  Node lastNode;  // 引用队列后端的结点
     public  LinkedQueue() {
         firstNode =  null ;
         lastNode =  null ;
     }
     private  class  Node  implements  Serializable {
         private  T data;  // entry in queue
         private  Node next;  // link to next queue
     }
     // 在后端插入
     public  void  enqueue(T newEntry) {
         Node newNode =  new  Node(newEntry,  null );
         if  (isEmpty())
             firstNode = newNode;
         else
             lastNode.setNext(newNode);
         lastNode = newNode;
     }
     // 删除前端元素
     public  T dequeue() {
         T front =  null ;
         if  (!isEmpty()) {
             front = firstNode.getData();
             firstNode = firstNode.getNext();
             if  (firstNode ==  null )
                 lastNode =  null ;
         }
         return  front;
     }
     // 检索前端元素
     public  T getFront() {
         T front =  null ;
         if  (!isEmpty())
             front = firstNode.getData();
         return  front;
     }
     public  boolean  isEmpty() {
         return  firstNode ==  null ;
     }
     public  void  clear() {
         firstNode =  null ;
         lastNode =  null ;
     }
}

3.基于(循环)数组的队列实现

131944558.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public  class  ArrayQueue<T>  implements  QueueInterface<T>, Serializable {
     private  T[] queue;  // 存放队列元素的循环数组
     private  int  frontIndex;
     private  int  backIndex;
     private  static  final  int  DEFAULT_INITIAL_CAPACITY =  50 ;
     public  ArrayQueue() {
         this (DEFAULT_INITIAL_CAPACITY);
     }
     public  ArrayQueue( int  initialCapacity) {
         queue = (T[])  new  Object[DEFAULT_INITIAL_CAPACITY +  1 ];
         frontIndex =  0 ;
         backIndex = initialCapacity;
     }
     // 在后端插入
     public  void  enqueue(T newEntry) {
         if  (isArrayFull()) {
             // 扩建数组
         }
         backIndex = (backIndex +  1 ) % queue.length;  // 由于数组是循环的,需要使用取余(%)操作符,以使backIndex达到其最大值之后变回0
         queue[backIndex] = newEntry;
     }
     // 删除前端元素
     public  T dequeue() {
         T front =  null ;
         if  (!isEmpty()) {
             front = queue[frontIndex];
             queue[frontIndex] =  null ;
             frontIndex = (frontIndex +  1 ) % queue.length;
         }
         return  front;
     }
     // 检索前端元素
     public  T getFront() {
         T front =  null ;
         if  (!isEmpty())
             front = queue[frontIndex];
         return  front;
     }
     public  boolean  isEmpty() {
         return  frontIndex == ((backIndex +  1 ) % queue.length);
     }
     private  boolean  isArrayFull() {
         return  frontIndex == ((backIndex +  2 ) % queue.length);
     }
}

4.基于双端链表的双端队列实现

132055795.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public  class  LinkedDeque<T>  implements  DequeInterface<T>, Serializable {
     private  DLNode firstNode;  // 引用双端队列的前端结点
     private  DLNode lastNode;  // 引用双端队列的后端结点
     public  LinkedDeque() {
         firstNode =  null ;
         lastNode =  null ;
     }
     private  class  DLNode  implements  Serializable {
         private  T data;
         private  DLNode next;
         private  DLNode previous;
     }
     // 插入元素
     public  void  addToBack(T newEntry) {
         DLNode newNode =  new  DLNode(newEntry, lastNode,  null );
         if (isEmpty())
             firstNode = newNode;
         else
             lastNode.setNext(newNode);
         lastNode = newNode;
     }
     public  void  addToFront(T newEntry) {
         DLNode newNode =  new  DLNode(newEntry,  null , firstNode);
         if (isEmpty())
             lastNode = newNode;
         else
             firstNode.setPrevious(newNode);
         firstNode = newNode;
     }
     // 删除元素
     public  T removeFront() {
         T front =  null ;
         if (!isEmpty()) {
             front = firstNode.getData();
             firstNode = firstNode.getNext();
             if (firstNode ==  null )
                 lastNode =  null ;
             else  firstNode.setPrevious( null );
         }
         return  front;
     }
     public  T removeBack() {
         T back =  null ;
         if (!isEmpty()) {
             back = lastNode.getData();
             lastNode = lastNode.getPrevious();
             if (lastNode ==  null )
                 firstNode =  null ;
             else
                 lastNode.setNext( null );
         }
         return  back;
     }
}

5.实现优先队列的方法

可以使用数组或链表实现优先队列。

132121823.png

但使用堆实现优先队列是一种更高效的方法。










本文转自 LinkedKeeper 51CTO博客,原文链接:http://blog.51cto.com/sauron/1226594,如需转载请自行联系原作者
目录
相关文章
|
1月前
|
算法
【优选算法专栏】专题十三:队列+宽搜(一)
【优选算法专栏】专题十三:队列+宽搜(一)
30 0
|
1月前
|
存储 算法 索引
【算法与数据结构】队列的实现详解
【算法与数据结构】队列的实现详解
159 0
|
4天前
|
机器学习/深度学习 存储 算法
数据结构与算法 动态规划(启发式搜索、遗传算法、强化学习待完善)
数据结构与算法 动态规划(启发式搜索、遗传算法、强化学习待完善)
11 1
|
4天前
|
存储 算法
数据结构与算法 栈与队列
数据结构与算法 栈与队列
10 0
数据结构与算法 栈与队列
|
7天前
|
搜索推荐 C语言
【C语言/数据结构】排序(归并排序|计数排序|排序算法复杂度)
【C语言/数据结构】排序(归并排序|计数排序|排序算法复杂度)
11 0
|
7天前
|
存储 算法
Leetcode 30天高效刷数据结构和算法 Day1 两数之和 —— 无序数组
给定一个无序整数数组和目标值,找出数组中和为目标值的两个数的下标。要求不重复且可按任意顺序返回。示例:输入nums = [2,7,11,15], target = 9,输出[0,1]。暴力解法时间复杂度O(n²),优化解法利用哈希表实现,时间复杂度O(n)。
19 0
|
13天前
|
存储 索引
操作数栈的字节码指令执行分析
操作数栈的字节码指令执行分析
|
14天前
|
存储 算法 Java
22个常用数据结构实现与原理分析
前两天V哥跟一个老学员吃饭,聊起面试大厂的事,说为啥大厂面试第一看基本条件,第二就是考数据结构算法,其他高阶的内容会比较少,最近V哥也在跟大厂对接这一块业务,了解得多一些,这是因为考察基本功能力被放到了重要位置,大厂认为硬性条件,比如学历过关,基本功够扎实,那对于实际工作用的上层技能,内部培养就好,也就是相比你掌握了多少多少牛逼的高阶技术,他们更在乎你的基本功,所以,进大厂,基本功必须要搞稳,否则白扯,今天 V 哥把总结好的22个常用的数据结构实现原理,和示例分析分享给大家,希望对你有帮助,觉得内容有收获,请帮忙转发给更多需求的朋友,共同进步。
|
14天前
|
存储 机器学习/深度学习 算法
|
18天前
|
存储 算法 Python
程序设计的艺术:算法与数据结构的魅力
程序设计的艺术:算法与数据结构的魅力
8 0