数据结构之栈
栈
栈的基本概念
- 栈是一种特殊的线性表,栈中的数据元素以及数据元素间的逻辑关系和线性表相同,两者之间的差别在于:线性表的插入和删除操作可以在表的任意进行,而栈的插入和删除操作只允许在表的尾端进行。其中,栈中只允许进行插入和删除操作的一端称为栈顶,另一端称为栈底。通常,将栈的插入操作称为入栈(push),而将删除操作称为出栈(pop)。
- 从栈的概念可知,每次最先入栈的数据元素总是被放在栈的底部,成为栈底元素;而每次最先出栈的总是那个放在栈顶位置的数据元素,即栈顶元素。因此,栈是一种后进先出(Last In First Out,LIFO)或先进后出(First In Last Out,FILO)的线性表。
栈的基本概念
栈也是由n(n≥0)个数据元素所构成的有限序列,其数据元素的类型可以任意,但只要是同一中类型即可。根据栈的特性,定义在栈的抽象数据类型中的基本操作如下:
- 置栈空操作clear():将一个已经存在的栈置成空栈。
- 判栈空操作isEmpty():判断一个栈是否为空,若栈为空,则返回true;否则,返回false。
- 求栈中数据元素个数操作length():返回栈中数据元素的个数。
- 取栈顶元素操作peek():读取栈顶元素并返回其值,若栈为空,则返回null。
- 入栈操作push(x):将数据元素x压入栈顶。
- 出栈操作pop():删除并返回栈顶元素。
1 /** 2 * 3 * @author Accper 4 * 5 */ 6 public interface IStack { 7 public void clear(); 8 public boolean isEmpty(); 9 public int length(); 10 public Object peek(); 11 public void push(Object x) throws Exception; 12 public Object pop(); 13 }
顺序栈及其基本操作的实现
顺序栈与顺序表一样,顺序栈也是用数组来实现的。假设数组名为stackElem。由于入栈和出栈操作只能在栈顶进行,所以需再加上一个变量top来指示栈顶元素的位置。top有两种定义方式:一种是将其设置为指向栈顶元素存储位置的下一个存储单元的位置,则空栈时,top=0;另一种是将top设置为指向栈顶元素的存储位置,则空栈时,top=-1。
1 /** 2 * 3 * @author Accper 4 * 5 */ 6 public class SqStack implements IStack { 7 // 对象数组 8 private Object[] stackElem; 9 // 在非空栈中,top始终指向栈顶元素的下一个储存位置;当栈为空时,top值为0 10 private int top; 11 12 // 栈的构造函数,构造一个储存空间容量为maxSize的空栈 13 public SqStack(int maxSize) { 14 // TODO Auto-generated constructor stub 15 top = 0; 16 stackElem = new Object[maxSize]; 17 } 18 19 // 栈为空 20 @Override 21 public void clear() { 22 // TODO Auto-generated method stub 23 top = 0; 24 } 25 26 // 判断栈是否为空 27 @Override 28 public boolean isEmpty() { 29 // TODO Auto-generated method stub 30 return top == 0; 31 } 32 33 // 求栈中数据元素的个数 34 @Override 35 public int length() { 36 // TODO Auto-generated method stub 37 return top; 38 } 39 40 // 取栈顶元素 41 @Override 42 public Object peek() { 43 // TODO Auto-generated method stub 44 if (!isEmpty()) { 45 return stackElem[top - 1]; 46 } else { 47 return null; 48 } 49 } 50 51 // 入栈操作 52 @Override 53 public void push(Object x) throws Exception { 54 // TODO Auto-generated method stub 55 if (top == stackElem.length) { 56 throw new RuntimeException("栈已经满了,无法进行入栈操作"); 57 } 58 stackElem[top++] = x; 59 } 60 61 // 出栈操作 62 @Override 63 public Object pop() { 64 // TODO Auto-generated method stub 65 if(isEmpty()){ 66 throw new RuntimeException("栈为空,无法进行出栈操作"); 67 } 68 return stackElem[--top]; 69 } 70 71 public void display() { 72 if(isEmpty()){ 73 System.out.println("栈为空"); 74 return; 75 } 76 for (int i = top - 1; i >= 0; i--) { 77 System.out.println(stackElem[i].toString()+" "); 78 } 79 } 80 81 // 测试 82 public static void main(String[] args) throws Exception { 83 SqStack stack = new SqStack(5); 84 System.out.println("栈是否为空:"+stack.isEmpty()); 85 stack.display(); 86 System.out.println("栈顶元素为:"+stack.peek()); 87 stack.push(1); 88 stack.push(2); 89 stack.push(3); 90 stack.push(4); 91 stack.push(5); 92 stack.display(); 93 System.out.println("栈顶元素为:"+stack.peek()); 94 System.out.println("出栈操作:"+stack.pop()); 95 System.out.println("======================"); 96 stack.display(); 97 98 } 99 }