《算法》学习笔记——背包(Bag)、队列(Queue)、栈(Stack)
2018-03-07 00:33
423 查看
每篇一句:
True love is not the temporary likeness, and I know it’s the feeling—meeting you is hard and it will be a pity if I miss you.概念介绍:
许多 基础数据类型 都和对象的 集合 有关。具体来说,数据类型的值就是一组对象的集合,所有的操作都是关于添加、删除或是访问集合中的对象。(感觉这句话翻译的很怪)而 背包(Bag)、队列(Queue)、栈(Stack) 就是这样的三种数据类型。背包(Bag): 背包是一种不支持从中删除元素的集合数据类型——它的目的就是帮助用例收集元素并迭代遍历所有收集到的元素。迭代的顺序不确定且与用例无关。在应用程序中使用Bag说明元素的 处理顺序不重要 。
先进先出队列(Queue): 先进先出队列(或简称队列)是一种基于 先进先出(FIFO) 策略的集合类型。当用例使用foreach语句迭代访问队列中的元素时,元素的处理顺序就是它们被添加到队列的顺序,在应用程序中使用队列的主要原因是在用集合保存元素的同时 保存它们的相对顺序 :使它们入列顺序和出列顺序相同。
下压栈(Stack): 下压栈(或简称栈)是一种基于 后进先出(LIFO) 策略的集合类型。当用例使用foreach语句迭代遍历栈中的元素时,元素的处理顺序和它们被压入的顺序 正好相反 。在应用程序中使用栈迭代器的一个典型原因是在用集合保存元素的同时 颠倒 它们的相对顺序。
代码实现:
下压堆栈(链表实现):public class Stack<Item> implements Iterable<Item> { private Node first; // 栈顶(最近添加的元素) private int N; // 元素数量 private class Node{ // 定义了节点的嵌套类 Item item; Node next; } public boolean isEmpty(){ return first == null; // 或:N == 0 } public int size(){ return N; } public void push(Item item){ // 向栈顶添加元素 Node oldfirst = first; first = new Node(); first.item = item; first.next = oldfirst; N++; } public 4000 Item pop(){ // 从栈顶删除元素 Item item = first.item; first = first.next; N--; return item; } @Override public Iterator<Item> iterator() { return new ListIterator(); } private class ListIterator implements Iterator<Item>{ private Node current = first; @Override public boolean hasNext() { return current != null; } @Override public Item next() { Item item = current.item; current = current.next; return item; } @Override public void remove() { } } }
先进先出队列(链表实现):
public class Queue<Item> implements Iterable<Item> { private Node first; // 指向最早添加的节点的链接 private Node last; // 指向最近添加的节点的链接 private int N; // 队列中的元素数量 private class Node{ // 定义了节点的嵌套类 Item item; Node next; } public boolean isEmpty(){ return first == null; // 或:N == 0 } public int size(){ return N; } public void enqueue(Item item){ // 向表尾添加元素 Node oldlast = last; last = new Node(); last.item = item; last.next = null; if (isEmpty()){ first = last; }else{ oldlast.next = last; } N++; } public Item dequeue(){ // 从表头删除元素 Item item = first.item; first = first.next; if (isEmpty()){ last = null; } N--; return item; } @Override public Iterator<Item> iterator() { return new ListIterator(); } private class ListIterator implements Iterator<Item>{ private Node current = first; @Override public boolean hasNext() { return current != null; } @Override public Item next() { Item item = current.item; current = current.next; return item; } @Override public void remove() { } } }
背包(链表实现):
public class Bag<Item> implements Iterable<Item> { private Node first; // 链表的首节点 private int N; private class Node{ // 定义了节点的嵌套类 Item item; Node next; } public void add(Item item){ // 和Stack的push() 方法完全相同 Node oldfirst = first; first = new Node(); first.item = item; first.next = oldfirst; N++; } public boolean isEmpty(){ return first == null; // 或:N == 0 } public int size(){ return N; } @Override public Iterator<Item> iterator() { return new ListIterator(); } private class ListIterator implements Iterator<Item>{ private Node current = first; @Override public boolean hasNext() { return current != null; } @Override public Item next() { Item item = current.item; current = current.next; return item; } @Override public void remove() { } }
另外,栈(Stack)除了用链表实现外,还有一种用数组实现的方式:
下压(LIFO)栈(能够动态调整数组大小的实现):
// 能够动态调整数组大小的实现 public class Stack_by_array<Item> implements Iterable<Item>{ private Item[] a = (Item[]) new Object[1]; private int N = 0; public boolean isEmpty(){ return N == 0; } public int size(){ return N; } private void resize(int max){ // 将栈移动到一个大小为max的新数组 Item[] temp = (Item[]) new Object[max]; for (int i = 0; i < N; i++){ temp[i] = a[i]; } a = temp; } public void push(Item item){ // 将元素添加到栈顶 if (N == a.length) resize(2 * a.length); a[N++] = item; } public Item pop(){ // 从栈顶删除元素 Item item = a[--N]; a = null; if (N > 0 && N == a.length / 4) resize(a.length / 2); return item; } @Override public Iterator<Item> iterator() { return new ReverseArrayIterator(); } private class ReverseArrayIterator implements Iterator<Item>{ // 支持后进先出的迭代 private int i = N; @Override public boolean hasNext() { return i > 0; } @Override public Item next() { return a[--i]; } @Override public void remove() { } } }
代码参考《算法》(第四版)——第一章
最后:
完整代码地址:Bag_Queue_Stack_Java(码云)相关文章推荐
- 栈(Stack)、队列(Queue)与包(Bag)的实现
- Implement queue with two stack 用两个堆实现队列
- JS中的队列(queue)和栈(stack)
- STL学习笔记6 -- 栈stack 、队列queue 和优先级priority_queue 三者比较
- C++基础:C++标准库之栈(stack)和队列(queue)
- 算法第四版读书笔记 - 背包、栈、队列
- 队列(queue)和堆栈(stack)的学习
- 【数据结构】第2周 栈与队列 3:stack or queue
- java数据结构与算法之(Queue)队列设计与实现
- erl_stack_queue-队列求迷宫最短路径
- 多重背包O(N*V)算法详解(使用单调队列)
- C++基础:C++标准库之栈(stack)和队列(queue)
- 使用单调队列优化的 O(nm) 多重背包算法
- 笔试算法题(57):基于堆的优先级队列实现和性能分析(Priority Queue based on Heap)
- C# 队列(Queue)和 堆栈(Stack)
- 多重背包O(N*V)算法详解(使用单调队列)(转载)
- [ACM训练] 算法初级 之 数据结构 之 栈stack+队列queue (基础+进阶+POJ 1338+2442+1442)
- Cpp的队列(Queue)学习笔记
- C++最大堆实现priority_queue优先级队列(算法导论)
- 利用Queue队列实现FIFO的算法