1 简介
- 队列:先进先出
- 栈:后进先出
- 栈是比较好实现的,队列实现起来有点麻烦
- 不保证线程安全,如果想要线程安全,可以在所有方法前加synchronized,但是这样做的话,明显是很糟糕的。你可以尝试加入读写锁。放置写入的时候执行其他操作。
2 栈
- 动态扩增的原理:当数组满的时候,自动创建新的数组,并把原数组的内容复制到新数组中。
package data.structure.stack;
public class ArrayStack<T> {
private Object[] datas;
private int capacity;
private int size;
private int alpha = 2;
private int cur;
private int start;
public ArrayStack() {
this.cur = 0;
this.start = 0;
this.capacity = 2;
datas = new Object[2];
}
public ArrayStack(int capacity) {
this.cur = 0;
this.start = 0;
this.capacity = capacity;
datas = new Object[capacity];
}
public boolean push(T o) {
if(cur == capacity){
resize();
}
datas[cur] = o;
cur++;
size++;
return true;
}
public T pop() {
if(size==0){
return null;
}else{
cur--;
size--;
return (T) datas[cur];
}
}
public T peek() {
if(size==0){
return null;
}else{
return (T) datas[cur-1];
}
}
public int size(){
return size;
}
private void resize(){
capacity = capacity * alpha;
Object[] temp = new Object[capacity];
for (int i = 0; i < datas.length; i++) {
temp[i] = datas[i];
}
datas = temp;
}
}
3 双栈实现队列
- 这种方式实现起来比较简单。
- 有两个数组实现,左侧数组用于放置数据。
- 当取数据的时候,如果右侧数组为空,则将左侧数组导入右侧数组,然后再从右侧数组取数据。如果右侧数组不为空,则直接取数据。
- 在左侧数组容量不足的时候,扩增左侧数组
- 在取数据的时候,如果右侧数组容量不足,则扩增右侧数组。
package data.structure.queue;
public class ArrayQueue<T> {
private Object[] leftArr;
private Object[] rightArr;
private int rightStart;
private int leftSize;
private int rightSize;
private int leftCapacity;
private int rightCapacity;
private int alpha=2;
public ArrayQueue() {
this.leftCapacity = 2;
this.rightCapacity = 2;
this.leftArr = new Object[2];
this.rightArr = new Object[2];
}
public ArrayQueue(int leftCapacity) {
this.leftCapacity = leftCapacity;
this.rightCapacity = leftCapacity;
this.leftArr = new Object[leftCapacity];
this.rightArr = new Object[leftCapacity];
}
public boolean push(T t){
if(leftSize==leftCapacity){
leftResize();
}
leftArr[leftSize] = t;
leftSize++;
return true;
}
public T poll(){
if(rightSize == 0){
leftToRight();
}
rightSize--;
rightStart++;
return (T) rightArr[rightStart-1];
}
public T peek(){
if(rightSize!=0){
return (T) rightArr[rightStart];
}else if(leftSize != 0){
return (T) leftArr[leftSize-1];
}else{
return null;
}
}
public int size(){
return leftSize + rightSize;
}
private void leftToRight(){
while(leftSize>rightCapacity){
rightResize();
}
for (int i = 0,size=leftSize; i < size; i++) {
rightArr[i] = leftArr[i];
leftSize--;
rightSize++;
}
rightStart = 0;
}
private void leftResize(){
leftCapacity = leftCapacity * alpha;
Object[] temp = new Object[leftCapacity];
for (int i = 0; i < leftArr.length; i++) {
temp[i] = leftArr[i];
}
leftArr = temp;
}
private void rightResize(){
rightCapacity = rightCapacity * alpha;
Object[] temp = new Object[rightCapacity];
for (int i = 0; i < rightArr.length; i++) {
temp[i] = rightArr[i];
}
rightArr = temp;
}
}
4 双向队列
- 要求既可以从左侧取数据,又可以从右侧取数据
- 并且在容量不足的时候要实现自动扩容。
package data.structure.queue;
public class CircleQueue<T> {
private int capacity;
private int size;
private int start;
private int end;
private int alpha = 2;
private Object[] datas;
public CircleQueue() {
this.capacity = 2;
datas = new Object[2];
size= 0;
start = 0;
end = 0;
}
public CircleQueue(int capacity) {
this.capacity = capacity;
datas = new Object[capacity];
size= 0;
start = 0;
end = 0;
}
public boolean push(T t){
if(size == capacity){
resize();
}
datas[end] = t;
end++;
size++;
if(end==capacity){
end = 0;
}
return true;
}
public T poll(){
if(size==0){
return null;
}
T result = (T)datas[start];
start++;
if(start==capacity){
start=0;
}
size--;
return result;
}
public T pop(){
if(size==0){
return null;
}
end--;
if(end==-1){
end = capacity-1;
}
size--;
return (T)datas[end];
}
public T lookFirt(){
if(size==0){
return null;
}
return (T)datas[start];
}
public T lookEnd(){
if(size==0){
return null;
}
if(end-1==-1){
return (T)datas[capacity-1];
}else{
return (T)datas[end-1];
}
}
public int size(){
return size;
}
private void resize(){
int lastCapacity = capacity;
capacity = capacity*alpha;
Object[] temp = new Object[capacity];
for (int i = 0; i < size; i++) {
if(start==lastCapacity-1){
start = 0;
}
temp[i] = datas[start];
start++;
}
start = 0;
end = size;
datas = temp;
}
}