棧
先進先出的數據結構
接口api接口抽象定義
public interface AbstractStack<T> {
void push(T t);
T pop();
T peek();
boolean isEmpty();
int size();
}
異常類定義
public class StackEmptyException extends RuntimeException{
public StackEmptyException(String message) {
super(message);
}
public StackEmptyException() {
super("棧爲空!!!");
}
}
用數組實現棧
用數組實現棧,這種方法存取數據在沒有擴容時時間複雜是O(1),如果遇到了擴容時間複雜度就變成了O(n),由於擴容的次數會相對的比push的次數少很多,所以push分攤了擴容的時間複雜度
public class ArrayStack<T> implements AbstractStack<T> {
private final static int DEFAULT_CAPACITY=100;
T[] stack;
private int top;
public ArrayStack() {
top=0;
stack= (T[]) new Object[DEFAULT_CAPACITY];
}
public ArrayStack(int initalCapacity) {
top=0;
stack= (T[]) new Object[initalCapacity];
}
@Override
public void push(T t) {
if (size()==stack.length){
expandCapacity();
}
stack[top]=t;
top++;
}
private void expandCapacity() {
Arrays.copyOf(stack,stack.length*2);
}
@Override
public T pop() throws StackEmptyException{
if (isEmpty()){
throw new StackEmptyException();
}
T result=stack[top];
stack[top]=null;
top--;
return result;
}
@Override
public T peek() throws StackEmptyException {
if (size()<=0){
throw new StackEmptyException();
}
return stack[top-1];
}
@Override
public boolean isEmpty() {
return stack.length>0?false:true;
}
@Override
public int size() {
return stack.length;
}
}
用鏈表實現棧
用鏈表實現棧,雖然不存在擴容,存取都是O(1),但是會使用跟多的空間,屬於空間換時間的做法
public class LinkedStack<T> implements AbstractStack<T> {
private LinkedNode<T> top;
private int count;
public LinkedStack() {
top=null;
count=0;
}
@Override
public void push(T t) {
LinkedNode<T> node=new LinkedNode<>(t);
node.setNext(top);
top=node;
count++;
}
@Override
public T pop() throws StackEmptyException{
if (isEmpty()){
throw new StackEmptyException();
}
T element = top.getElement();
top=top.getNext();
count--;
return element;
}
@Override
public T peek() throws StackEmptyException{
if (isEmpty()){
throw new StackEmptyException();
}
return top.getElement();
}
@Override
public boolean isEmpty() {
return size()>0?false:true;
}
@Override
public int size() {
return count;
}
class LinkedNode<T>{
private LinkedNode<T> next;
private T element;
public LinkedNode() {
next=null;
element=null;
}
public LinkedNode(T element) {
next=null;
this.element = element;
}
public T getElement() {
return element;
}
public void setElement(T element) {
this.element = element;
}
public void setNext(LinkedNode<T> next) {
this.next = next;
}
public LinkedNode<T> getNext() {
return next;
}
}
}
隊列
一個先進後出的數據結構,也可以說是先來後到或者先到先得
接口抽象定義
public interface AbstrackQueue<T> {
void enqueue(T element);
T dequeue();
int size();
boolean isEmpty();
T first();
}
異常類定義
public class QueueEmptyException extends RuntimeException {
public QueueEmptyException() {
super("隊列爲空!!!!");
}
public QueueEmptyException(String message) {
super(message);
}
}
用鏈表實現隊列
存取都是O(1),但是使用了更多的空間
public class LinkedQueue<T> implements AbstrackQueue<T> {
private int count;
private LinkedNode<T> head,tail;
public LinkedQueue() {
count=0;
head=tail=null;
}
@Override
public void enqueue(T element) {
LinkedNode<T> node=new LinkedNode<>(element);
if (isEmpty()){
head=node;
}else {
tail.setNext(node);
}
tail=node;
count++;
}
@Override
public T dequeue() throws QueueEmptyException{
if (isEmpty()){
throw new QueueEmptyException();
}
T result = head.element;
head=head.getNext();
count++;
if (isEmpty()){
tail=null;
}
return result;
}
@Override
public int size() {
return count;
}
@Override
public boolean isEmpty() {
return size()>0?false:true;
}
@Override
public T first() throws QueueEmptyException{
if (isEmpty()){
throw new QueueEmptyException();
}
return head.getElement();
}
class LinkedNode<T>{
private LinkedNode<T> next;
private T element;
public LinkedNode() {
next=null;
element=null;
}
public LinkedNode(T element) {
next=null;
this.element = element;
}
public T getElement() {
return element;
}
public void setElement(T element) {
this.element = element;
}
public void setNext(LinkedNode<T> next) {
this.next = next;
}
public LinkedNode<T> getNext() {
return next;
}
}
}
使用數組實現隊列(循環隊列)
使用數組需要考慮的是數組移動的問題,每當dequeue一個元素時,數組都得往前移動n-1個位置,這樣效率太低了,所以使用環形數組的形式
公式:front代表隊列的首元素存儲的位置,rear是數組的下一個可用的數組下標,arrays是數組,index=(index+1)%arrays.length,當rear爲0時,代表了數組已經被填充滿了
public class ArrayQueue<T> implements AbstrackQueue<T> {
private final static int DEFAULT_CAPACITY=100;
private int front,rear,count;
private T[] queque;
public ArrayQueue() {
this(DEFAULT_CAPACITY);
front=rear=count=0;
}
public ArrayQueue(int initialCapacity) {
front=rear=count=0;
queque= (T[]) new Object[initialCapacity];
}
@Override
public void enqueue(T element) {
if (size()==queque.length){
expandCapacity();
}
queque[rear]=element;
rear=(rear+1)%queque.length;
count++;
}
private void expandCapacity() {
T[] newCapacity= (T[]) new Object[queque.length*2];
for (int i=0;i<count;i++){
newCapacity[i]=queque[front];
front=(front+1)%queque.length;
}
front=0;
rear=count;
}
@Override
public T dequeue() throws QueueEmptyException{
if (isEmpty()){
throw new QueueEmptyException();
}
T result = queque[front];
queque[rear]=null;
front=(front+1)%queque.length;
count--;
return result;
}
@Override
public int size() {
return count;
}
@Override
public boolean isEmpty() {
return size()>0?false:true;
}
@Override
public T first() {
return queque[front];
}
}