溫習Algs4 (一):揹包, 棧, 佇列和線性表
阿新 • • 發佈:2018-12-21
揹包, 棧, 佇列和線性表
揹包
揹包是最簡單的資料結構, 只有新增資料和遍歷元素兩個功能, 內部實現是連結串列.
Bag.java
/******************************************************************************
* Compilation: javac Bag.java
* Execution: java Bag
* Author: Chenghao Wang
******************************************************************************/
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Bag<T> implements Iterable<T> {
private class Node {
private T item;
private Node next;
Node(T item) {
this.item = item;
next = null;
}
}
private class BagIterator implements Iterator<T> {
private Node current = head;
@Override
public boolean hasNext() {
return current != null;
}
@Override
public T next() {
if (current == null) throw new NoSuchElementException() ;
T result = current.item;
current = current.next;
return result;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
private Node head = null;
public void add(T item) {
Node n = new Node(item);
n.next = head;
head = n;
}
@Override
public Iterator<T> iterator() {
return new BagIterator();
}
}
複雜度分析
- add: O(1)
棧
棧支援的功能有壓棧, 出棧, 查詢棧頂元素, 檢查是否為空和查詢元素個數. 內部實現也是連結串列.
Stack.java
/******************************************************************************
* Compilation: javac Stack.java
* Execution: java Stack
* Author: Chenghao Wang
******************************************************************************/
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Stack<T> implements Iterable<T> {
private class Node {
private T item;
private Node next;
Node(T item) {
this.item = item;
next = null;
}
}
private class StackIterator implements Iterator<T> {
private Node current = head;
@Override
public boolean hasNext() {
return current != null;
}
@Override
public T next() {
if (current == null) throw new NoSuchElementException();
T result = current.item;
current = current.next;
return result;
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
private Node head = null;
private int size = 0;
public void push(T item) {
Node n = new Node(item);
n.next = head;
head = n;
size++;
}
public T pop() {
if (size == 0) {
throw new NoSuchElementException();
}
size--;
T result = head.item;
head = head.next;
return result;
}
public T top() {
if (size == 0) {
throw new NoSuchElementException();
}
return head.item;
}
public boolean isEmpty() {
return size == 0;
}
public int size() {
return size;
}
public Iterator<T> iterator() {
return new StackIterator();
}
}
複雜度分析
- push: O(1)
- pop: O(1)
- isEmpty: O(1)
- size: O(1)
佇列
佇列支援的功能有入列, 出列, 檢查是否為空和查詢元素個數. 內部實現也是連結串列.
Queue.java
/******************************************************************************
* Compilation: javac Queue.java
* Execution: java Queue
* Author: Chenghao Wang
******************************************************************************/
import java.util.NoSuchElementException;
import java.util.Iterator;
public class Queue<T> implements Iterable<T> {
private class Node {
private T item;
private Node next;
Node(T item) {
this.item = item;
next = null;
}
}
private class QueueIterator implements Iterator<T> {
private Node current = head;
public boolean hasNext() {
return current != null;
}
public T next() {
if (current == null) throw new NoSuchElementException();
T result = current.item;
current = current.next;
return result;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
private Node head = null;
private Node tail = null;
private int size = 0;
public void enqueue(T item) {
Node n = new Node(item);
if (head == null) head = n;
else tail.next = n;
tail = n;
size++;
}
public T dequeue() {
if (size == 0) {
throw new NoSuchElementException();
}
size--;
T result = head.item;
head = head.next;
return result;
}
public boolean isEmpty() {
return size == 0;
}
public int size() {
return size;
}
public Iterator<T> iterator() {
return new QueueIterator();
}
}
複雜度分析
- enqueue: O(1)
- dequeue: O(1)
- isEmpty: O(1)
- size: O(1)
線性表
線性表即為動態陣列, 支援的方法是對元素的增刪查改, 查詢是否為空和元素個數.
Vector.java
/******************************************************************************
* Compilation: javac Vector.java
* Execution: java Vector
* Author: Chenghao Wang
******************************************************************************/
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Vector<T> implements Iterable<T> {
private class VectorIterator implements Iterator<T> {
private int ptr = 0;
@Override
public boolean hasNext() {
return ptr < size;
}
@Override
public T next() {
if (ptr >= size) {
throw new NoSuchElementException();
}
return content[ptr++];
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}
private static final int INITIAL_CAPACITY = 8;
private int capacity;
private int size;
private T[] content;
Vector() {
content = (T[]) new Object[INITIAL_CAPACITY];
capacity = INITIAL_CAPACITY;
size = 0;
}
void insert(int index, T item) {
if ((index < 0) || (index > size)) {
throw new IllegalArgumentException();
}
size++;
for (int i = size - 1; i > index; i++) {
content[i] = content[i - 1];
}
content[index] = item;
if (size == capacity) {
resize(capacity * 2);
}
}
void add(T item) {
insert(size, item);
}
void remove(int index) {
if ((index < 0) || (index >= size)) {
throw new IllegalArgumentException();
}
size--;
for (int i = index; i < size; i++) {
content[i] = content[i+1];
}
if ((size < (capacity / 8)) && (size > 1)) {
resize(capacity / 4);
}
}
T get(int index) {
if ((index < 0) || (index >= size)) {
throw new IllegalArgumentException();
}
return content[index];
}
void set(int index, T item) {
if ((index < 0) || (index >= size)) {
throw new IllegalArgumentException();
}
content[index] = item;
}
void resize(int c) {
capacity = c;
T[] newContent = (T[]) new Object[capacity];
for (int i = 0; i < size; i++) {
newContent[i] = content[i];
}
content = newContent;
}
boolean isEmpty() {
return size == 0;
}
int size() {
return size;
}
@Override
public Iterator<T> iterator() {
return new VectorIterator();
}
}
複雜度分析
- add: O(1)
- insert: O(n)
- remove: O(n)
- set: O(1)
- isEmpty: O(1)
- size: O(1)
總結
最近打算重新複習和鞏固一下基礎演算法, 先從最基本的資料結構入手, 將Algorithms 4th Ed. 的所有演算法和資料結構重新實現一遍.