栈
栈是一种只允许在一端进行插入或删除的线性表。
1、栈的操作端通常被称为栈顶,另一端被称为栈底。
2、栈的插入操作称为进栈(压栈|push);栈删除操作称为出栈(弹栈|pop)。
- 定义一个栈接口:
/*
* 线性表的一种特殊情况
* */
public interface Stack<E> extends Iterable<E>{
int getSize();
boolean isEmpty();
void push(E e);
E pop();
E peek();
void clear();
}
- 通过顺序表实现栈(顺序栈):
private static int DEFAULT_SiZE=10;//默认容量
private int top;//栈顶指针
private int[] data;
//创建一个栈使用默认容量
public ArrayStack(){
this(DEFAULT_SiZE);
}
//创建一个栈使用用户指定容量capacity
public ArrayStack(int capacity){
super();
this.top=-1;
this.data=new int[capacity];
}
//入栈一个元素
public void push(int e){
if(top==data.length-1){
System.out.println("栈已满!无法入栈元素");
}
data[++top]=e;
}
//出栈一个元素
public int pop(){
if(isEmpty()){
System.out.println("栈已空!无法出栈元素");
}
return data[top--];
}
//判断栈是否为空
public boolean isEmpty(){
return this.top==-1;
}
//获取有效元素的个数
public int length(){
return this.top+1;
}
public String toString(){
StringBuilder sb=new StringBuilder();
sb.append('[');
for(int i=0;i<=top;i++){
sb.append(data[i]);
if(i==top)
return sb.append(']').toString();
sb.append(',');
sb.append(' ');
}
return "[]";
}
}
- 双端顺序栈:
package DS01.动态数组;
import java.util.Iterator;
/*
* 双端栈*/
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;
}
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;
}
public void pushRight(E e){
if(rightTop-1==leftTop){
resize(2*data.length);//扩容
}
rightTop--;
data[rightTop]=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[rightTop--];
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 [] bottom\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;
}
private class ArrayStackDoubleEndIterator implements Iterator{
@Override
public boolean hasNext() {
return false;
}
@Override
public Object next() {
return null;
}
}
}
- 通过链表实现栈(链栈):
import DS01.动态数组.Stack;
import DS02.动态链表.LinkedList;
import java.util.Iterator;
public class LinkedStack<E> implements Stack<E> {
private LinkedList<E> list;
public LinkedStack(){
list=new LinkedList();
}
@Override
public int getSize() {
return list.getSize();
}
@Override
public boolean isEmpty() {
return list.isEmpty();
}
@Override
public void push(E e) {
list.addFirst(e);
}
@Override
public E pop() {
return list.removeFirst();
}
@Override
public E peek() {
return list.getFirst();
}
@Override
public void clear() {
list.clear();
}
@Override
public Iterator<E> iterator() {
return list.iterator();
}
}
- 双端链栈:
package DS02.动态链表;
import DS01.动态数组.Stack;
import java.util.Iterator;
public class LinkedStackDoubleEnd<E> implements Stack<E> {
private Node left;
private Node right;
private int leftSize;
private int rightSize;
public LinkedStackDoubleEnd(){
left=new Node();
right=new Node();
left.next=right;
leftSize=0;
rightSize=0;
}
private class Node{
E data;
Node next;
Node(){
this(null,null);
}
Node(E data,Node next){
this.data=data;
this.next=next;
}
public String toString(){
return data.toString();
}
}
public int getLeftSize(){
return leftSize;
}
public int getRightSize(){
return rightSize;
}
@Override
public int getSize() {
return leftSize+rightSize;
}
public boolean isLeftisEmpty(){
return leftSize==0;
}
public boolean isRightisEmpty(){
return rightSize==0;
}
@Override
public boolean isEmpty() {
return isLeftisEmpty()&&isRightisEmpty();
}
public void pushLeft(E e){
left.next=new Node(e,left.next);
leftSize++;
}
public void pushRight(E e){
right.next=new Node(e,right.next);
rightSize++;
}
@Override
public void push(E e) {
if(leftSize<=rightSize){
pushLeft(e);
}else {
pushRight(e);
}
}
public E popLeft(){
if(isLeftisEmpty()){
throw new IllegalArgumentException("左边为空");
}
E ret=left.next.data;
left.next=left.next.next;
leftSize--;
return ret;
}
public E popRight(){
if(isLeftisEmpty()){
throw new IllegalArgumentException("右边为空");
}
E ret=right.next.data;
right.next=right.next.next;
rightSize--;
return ret;
}
@Override
public E pop() {
if(leftSize>=rightSize){
return popLeft();
}else {
return popRight();
}
}
public E peekLeft(){
if(isLeftisEmpty()){
throw new IllegalArgumentException("左边为空");
}
return left.next.data;
}
public E peekRight(){
if(isLeftisEmpty()){
throw new IllegalArgumentException("右边为空");
}
return right.next.data;
}
@Override
public E peek() {
return leftSize>=rightSize?peekLeft():peekRight();
}
public void clearLeft(){
left.next=right;
leftSize=0;
}
public void clearRight(){
right.next=null;
rightSize=0;
}
@Override
public void clear() {
clearLeft();
clearRight();
}
@Override
public Iterator<E> iterator() {
return null;
}
}