一、知识总结(笔记)
二、实现代码
1.双端栈
package part01;
import java.util.Iterator;
import javax.sound.midi.SysexMessage;
public class ArrayDoubleEndStack<E> implements Iterable<E>{
public static void main(String[] args) {
ArrayDoubleEndStack<Integer> stack = new ArrayDoubleEndStack<Integer>();
for(int i = 1 ; i < 8 ; i++) {
stack.push(i, 0);
stack.push(i, 1);
}
System.out.println(stack);
for(int token : stack) {
System.out.print(token + " ");
}
}
private E[] data;
private int ltop;
private int rtop;
private static int DEFAULT_SIZE = 10;
public ArrayDoubleEndStack() {
data = (E[]) new Object[DEFAULT_SIZE];
ltop = -1;
rtop = data.length;
}
//入栈
public void push(E element , int stackId) {
if(ltop + 1 == rtop) {
resize(data.length * 2);
}
switch(stackId) {
case 0:
data[++ltop] = element;
break;
case 1:
data[--rtop] = element;
break;
}
}
//判断某一栈是否为空
public boolean isEmpity(int stackId) {
switch(stackId) {
case 0:
return ltop == -1;
case 1:
return rtop == data.length;
}
return false;
}
//出栈
public E pop(int stackId) {
if(isEmpity(stackId)) {
throw new IllegalArgumentException("stack is null");
}
E ret = null;
switch(stackId) {
case 0 :
ret = data[ltop--];
break;
case 1 :
ret = data[rtop];
rtop += 1;
break;
}
if(size(0) + size(1) == data.length / 4 && data.length > DEFAULT_SIZE) {
resize(data.length / 2);
}
return ret;
}
//某个栈的有效元素个数
public int size(int stackId) {
switch(stackId) {
case 0 :
return ltop + 1;
case 1 :
return data.length - rtop;
}
return -1;
}
//清空某个栈
public void clear(int stackId) {
switch(stackId) {
case 0 :
ltop = -1;
break;
case 1 :
rtop = data.length;
break;
}
}
//某个栈栈顶元素
public E peek(int stackId) {
if(isEmpity(stackId)) {
throw new IllegalArgumentException("stack is null");
}
switch(stackId) {
case 0 :
return data[ltop];
case 1 :
return data[rtop];
}
return null;
}
//扩/缩 容
private void resize(int newLen) {
E[] newData =(E[]) new Object[newLen];
for(int i = 0 ; i < ltop+1 ;i++) {
newData[i] = data[i];
}
int s = rtop;
for(int j = newLen - size(1) ; j < newLen ; j++) {
newData[j] = data[s++];
}
rtop = newLen - size(1);
data = newData;
}
public String toString() {
StringBuilder sb = new StringBuilder(String.format("ArrayDoubleEndStack:%d / %d\n", size(0)+size(1), data.length));
if(isEmpity(0)) {
sb.append("leftStack:[]");
}else {
sb.append("leftStack:[");
for(int i = 0 ; i <= ltop ; i++){
sb.append(data[i]);
if(i == ltop) {
sb.append("]");
sb.append('\n');
}else {
sb.append(" ,");
}
}
}
if(isEmpity(1)) {
sb.append("rightStack:[]");
}else {
sb.append("rightStack:[");
for(int i = rtop ; i < data.length ; i++) {
sb.append(data[i]);
if(i == data.length - 1) {
sb.append("]");
sb.append('\n');
}else {
sb.append(" ,");
}
}
}
return sb.toString();
}
@Override
public Iterator<E> iterator() {
return new ArrayDoubleEndStackIterator();
}
class ArrayDoubleEndStackIterator implements Iterator<E>{
private ArrayList<E> list;
private Iterator<E> it;
public ArrayDoubleEndStackIterator() {
list = new ArrayList<>();
for(int i = 0 ; i < size(0) ; i++) {
list.add(data[i]);
}
for(int i = rtop ; i < data.length ; i++) {
list.add(data[i]);
}
it = list.iterator();
}
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public E next() {
return it.next();
}
}
}
2.循环队列
package part01;
import java.util.Iterator;
import 数据结构接口.Queue;
public class ArrayLoopQueue<E> implements Queue<E>{
private E data[];
private int front;
private int rear;
private static int DEFAULT_CAPACITY = 10;
private int size;
public ArrayLoopQueue() {
data = (E[])new Object[DEFAULT_CAPACITY + 1];
front = 0;
rear = 0;
size = 0;
}
@Override
public Iterator<E> iterator() {
return new ArrayLoopQueueIterator<E>();
}
class ArrayLoopQueueIterator<E> implements Iterator<E>{
private int cur = front;
@Override
public boolean hasNext() {
return (rear + 1) % data.length != front;
}
@Override
public E next() {
E ret = (E) data[cur];
cur = (cur + 1) % data.length;
return ret;
}
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public void clear() {
data = (E[])new Object[DEFAULT_CAPACITY + 1];
front = 0;
rear = 0;
size = 0;
}
@Override
public void offer(E element) {
if((rear + 1) % (data.length) == front) {
resize(data.length * 2 - 1);
}
data[rear] = element;
rear = (rear +1) % (data.length);
size++;
}
@Override
public E element() {
if(rear == front) {
throw new IllegalArgumentException("queue is null");
}
return data[front];
}
@Override
public E poll() {
if(rear == front) {
throw new IllegalArgumentException("queue is null");
}
E ret = data[front];
front = (front + 1) % data.length;
size--;
if(size <= (data.length - 1) /4 && data.length - 1 > DEFAULT_CAPACITY) {
resize(data.length / 2 + 1);
}
return ret;
}
private void resize(int newLen) {
E[] newData = (E[]) new Object[newLen];
int index = 0;
for(int i = front ; i != rear ; i = (i+1) % data.length) {
newData[index++] = data[i];
}
data = newData;
front = 0;
rear = index;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(String.format("ArrayLoopQueue:%d / %d\n", size, data.length));
sb.append('[');
if (isEmpty()) {
sb.append(']');
return sb.toString();
}
for (int i = front; i != rear; i = (i + 1) % data.length) {
sb.append(data[i]);
if ((i + 1) % data.length == rear) {
sb.append(']');
} else {
sb.append(',');
sb.append(' ');
}
}
return sb.toString();
}
@Override
public boolean equals(Object obj) {
if(obj == null) {
return false;
}
if(this == obj) {
return true;
}
if(obj instanceof ArrayLoopQueue) {
ArrayLoopQueue<E> other = (ArrayLoopQueue<E>) obj;
if(size != other.size) {
return false;
}
int i = front;
int j = other.front;
while(i != rear) {
if(!data[i].equals(other.data[j])) {
return false;
}
i = (i+1) % data.length;
j = (j+1) % other.data.length;
}
return true;
}
return false;
}
}
3.双端循环队列
package part01;
import java.util.Iterator;
import 数据结构接口.Dequeue;
import 数据结构接口.Stack;
public class ArrayDeque<E> implements Dequeue<E>,Stack<E>{
private E[] data;
private int front;
private int rear;
private int size;
private static int DEFAULT_CAPACITY = 10;
public ArrayDeque() {
data = (E[]) new Object[DEFAULT_CAPACITY + 1];
front = 0;
rear = 0;
size = 0;
}
@Override
public int size() {
return size;
}
@Override
public boolean isEmpty() {
return size == 0;
}
@Override
public void clear() {
data = (E[]) new Object[DEFAULT_CAPACITY + 1];
front = 0;
rear = 0;
size = 0;
}
@Override
public void offer(E element) {
addLast(element);
}
@Override
public E element() {
return getFirst();
}
@Override
public E poll() {
return removeFirst();
}
@Override
public void push(E element) {
addLast(element);
}
@Override
public E pop() {
return removeLast();
}
@Override
public E peek() {
return getLast();
}
@Override
public void addFirst(E element) {
if((rear+1) % data.length == front) {
resize(data.length * 2 - 1);
}
front = (front - 1 + data.length) % data.length;
data[front] = element;
size++;
}
@Override
public void addLast(E element) {
if((rear+1) % data.length == front) {
resize(data.length * 2 - 1);
}
data[rear] = element;
rear = (rear + 1) % data.length;
size++;
}
@Override
public E removeFirst() {
if(size == 0) {
throw new IllegalArgumentException("queue is null");
}
E ret = data[front];
front = (front + 1) % data.length;
size--;
if(size <= (data.length - 1) / 4 && (data.length - 1) > DEFAULT_CAPACITY) {
resize(data.length / 2 + 1);
}
return ret;
}
@Override
public E removeLast() {
if(size == 0) {
throw new IllegalArgumentException("queue is null");
}
E ret = data[(rear - 1 + data.length) % data.length];
rear = (rear - 1 + data.length) % data.length;
size--;
if(size <= (data.length - 1) / 4 && (data.length - 1) > DEFAULT_CAPACITY) {
resize(data.length / 2 + 1);
}
return ret;
}
private void resize(int newLen) {
E newData[] = (E[]) new Object[newLen];
int j = 0;
for(int i = front ; i != rear ; i = (i + 1) % data.length) {
newData[j++] = data[i];
}
data = newData;
front = 0;
rear = j;
}
@Override
public E getFirst() {
if(size == 0) {
throw new IllegalArgumentException("queue is null");
}
return data[front];
}
@Override
public E getLast() {
if(size == 0) {
throw new IllegalArgumentException("queue is null");
}
return data[(rear - 1 + data.length) % data.length];
}
@Override
public Iterator<E> iterator() {
return new ArrayDequeItertor();
}
class ArrayDequeItertor implements Iterator<E>{
private int cur = front;
@Override
public boolean hasNext() {
return cur != rear;
}
@Override
public E next() {
E ret = data[cur];
cur = (cur + 1) % data.length;
return ret;
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder(String.format("ArrayDeque: %d / %d", size , data.length-1));
if(size == 0) {
sb.append("[]");
return sb.toString();
}
sb.append("[");
for(int i = front ; i != rear ; i = (i + 1) % data.length) {
sb.append(data[i]);
if((i + 1) % data.length == rear) {
sb.append("]");
}else {
sb.append(" ,");
}
}
return sb.toString();
}
}