1)棧的定義
棧是限定僅在表尾進行插入和刪除操作的線性表
- 我們把允許插入和刪除的一端稱爲棧頂(top),另一端稱爲棧底(bottom)
- 不含任何數據元素的棧稱爲空棧
- 棧又稱爲後進先出(Last In First Out)的線性表,簡稱LIFO結構
- 棧本身是一個線性表,其數據元素具有線性關係,只不過它是一種特殊的線性表而已
- 定義中說的是在線性表的表尾進行插入和刪除操作,這裏表尾是指棧頂,而不是棧底
- 棧的插入操作,叫作進棧,也稱壓棧、入棧
- 棧的刪除操作,叫作出棧,也稱彈棧
2)棧接口Stack的定義
public interface Stack<E> extends Iterable<E>{
//獲取棧中元素個數
int getSize();
//是否爲空
boolean isEmpty();
//進棧
void push(E e);
//出棧
E pop();
//查看棧
E peek();
//清空
void clear();
}
3)棧的順序存儲結構ArrayStack的定義
import java.util.Iterator;
public class ArrayStack<E> implements Stack<E>{
private ArrayList<E> list;
//創建一個默認大小的棧
public ArrayStack(){
list=new ArrayList<>();
}
//創建一個指定大小的棧
public ArrayStack(int capacity){
list =new ArrayList<E>(capacity);
}
@Override
public int getSize(){
return list.getSize();
}
@Override
public boolean isEmpty(){
return list.isEmpty();
}
@Override
public void push(E e){
list.addLast(e);
}
@Override
public E pop(){
return list.removeLast();
}
@Override
public E peek(){
return list.getLast();
}
//清空
public void clear(){
list.clear();
}
@Override
public Iterator<E> iterator(){
return list.iterator();
}
}
4)雙端棧的定義
是指將一個線性表的兩端當做棧底分別進行入棧和出棧操作
5)雙端棧的順序存儲結構ArrayStackDoubleEnd的定義
public class ArrayStackDoubleEnd<E> implements Stack<E>{
private static final int DEFAULT_SIZE=10;
private E[] data;
private int leftTop;
private int rightTop;
public ArrayStackDoubleEnd(){
this(DEFAULT_SIZE);
}
public ArrayStackDoubleEnd(int capacity){
data=(E[])(new Object[capacity]);
leftTop=-1;
rightTop=data.length;
}
//獲取左棧中有效元素個數
public int getLeftSize(){
return leftTop+1;
}
//獲取右棧中有效元素個數
public int getRightSize(){
return data.length-rightTop;
}
//獲取棧中所有元素的個數
@Override
public int getSize() {
return getLeftSize()+getRightSize();
}
//判斷左棧是否爲空
public boolean isLeftEmpty(){
return leftTop==-1;
}
//判斷右棧是否爲空
public boolean isRightEmpty(){
return rightTop==data.length;
}
//判斷棧是否爲空
@Override
public boolean isEmpty() {
return isLeftEmpty()&&isRightEmpty();
}
//在左棧進棧
public void pushLeft(E e){
//滿了擴容
if(leftTop+1==rightTop){
resize(2*data.length);
}
leftTop++;
data[leftTop]=e;
}
//在右棧進棧
public void pushRight(E e){
if(rightTop-1==leftTop){
resize(2*data.length);
}
rightTop--;
data[rightTop]=e;
}
private void resize(int newLen){
E[] newData=(E[])(new Object[newLen]);
//擴容和縮容時左邊的複製
for(int i=0;i<=leftTop;i++){
newData[i]=data[i];
}
//擴容時右邊的複製
if(newData.length>data.length){
for(int i=rightTop;i<data.length;i++){
newData[i+data.length]=data[i];
}
rightTop=rightTop+data.length;
}else{//縮容時右邊的複製
for(int i=rightTop;i<data.length;i++){
newData[i-newData.length]=data[i];
}
rightTop=rightTop-newData.length;
}
data=newData;
}
//進棧元素e
@Override
public void push(E e) {
if(getLeftSize()<=getRightSize()){
pushLeft(e);
}else{
pushRight(e);
}
}
public E popLeft(){
if(isLeftEmpty()){
throw new IllegalArgumentException("左棧爲空");
}
E ret=data[leftTop--];
if(getSize()<=data.length/4&&data.length/2>10){
resize(data.length/2);
}
return ret;
}
public E popRight(){
if(isRightEmpty()){
throw new IllegalArgumentException("右棧爲空");
}
E ret=data[rightTop++];
if(getSize()<=data.length/4&&data.length/2>=10){
resize(data.length/2);
}
return ret;
}
@Override
public E pop() {
if(getLeftSize()>=getRightSize()){
return popLeft();
}else{
return popRight();
}
}
public E peekLeft(){
if(isLeftEmpty()){
throw new IllegalArgumentException("左棧爲空");
}
return data[leftTop];
}
public E peekRight(){
if(isRightEmpty()){
throw new IllegalArgumentException("右棧爲空");
}
return data[rightTop];
}
@Override
public E peek() {
if(getLeftSize()>=getRightSize()){
return peekLeft();
}else{
return peekRight();
}
}
@Override
public void clear() {
data= (E[]) new Object[DEFAULT_SIZE];
leftTop=-1;
rightTop=data.length;
}
@Override
public String toString() {
StringBuilder sb=new StringBuilder();
sb.append(String.format("ArrayStackDoubleEnd: %d/%d\n",getSize(),data.length));
if(isLeftEmpty()){
sb.append("left :bottom [] top");
}else{
sb.append("left :bottom [");
for(int i=0;i<=leftTop;i++){
sb.append(data[i]);
if(i==leftTop){
sb.append("] top");
}else{
sb.append(',');
}
}
}
sb.append('\n');
if(isRightEmpty()){
sb.append("right:top [] bootom\n");
}else {
sb.append("right:top [");
for(int i=rightTop;i<data.length;i++){
sb.append(data[i]);
if(i==data.length-1){
sb.append("] bottom");
}else{
sb.append(',');
}
}
}
return sb.toString();
}
@Override
public Iterator<E> iterator() {
return null;
}
}