栈的基本知识和栈的应用举例
栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
对于不同的数据结构有着不同的作用,如:数组、链表、树等都适用于数据库应用,通常用来存储数据或记录;而对于栈和队列来说,由于它们都是受限访问的,所以更加的抽象,通常作为程序员的工具来运用,作为构思算法的辅助工具。
- 这里的受限是指:数组可通过下标随时存储和访问数据,但栈和队列只能在某种特定情况(出栈或入栈)时可取出或压进一个数据;
- 栈就是一组记录,表现形式为:先进后出;(重点)
- 栈的实现受其表现形式的约定,但底层的存储一般采用数组或链接实现;
- 栈的基本算法:
1.进栈(PUSH)算法
①若TOP≥n时,则给出溢出信息,作出错处理(进栈前首先检查栈是否已满,满则溢出;不满则作②);
②置TOP=TOP+1(栈指针加1,指向进栈地址);
③S(TOP)=X,结束(X为新进栈的元素);
2.退栈(POP)算法
①若TOP≤0,则给出下溢信息,作出错处理(退栈前先检查是否已为空栈, 空则下溢;不空则作②);
②X=S(TOP),(退栈后的元素赋给X):
③TOP=TOP-1,结束(栈指针减1,指向栈顶)。 - 代码实现:(以下用java代码简单实现类栈的工作原理)
创建一个stack类:
/**
*
* @author 磊大大
*/
public class StackX {
private long[] stackArray;
private int maxSize;
private int top;
public StackX(int s){
maxSize = s;
stackArray = new long[maxSize];
top = -1;
}
//入栈
public void push(long j){
if(!isFull()) //检测是否栈满,满则不能入栈
stackArray[++top] = j; //此处必须先++,因为top=-1
else
System.out.println("Stack is fulling!");
}
//出栈
public long pop(){
if(!isEmpty()) //检测是否为空,为空则不能出栈
return stackArray[top--]; //出栈后,栈顶指针需要下移
else{
System.out.println("Stack is empty!");
return 0;
}
}
//查看栈顶元素
public long peek(){
return stackArray[top];
}
//判断栈是否为空
public boolean isEmpty(){
return top==-1;
}
//判断栈是否为满
public boolean isFull(){
return top==(maxSize-1);
}
}
创建一个测试类:
/**
*
* @author 磊大大
*/
public class StackApp {
public static void main(String[] args){
StackX stackArray = new StackX(5);
//入栈
stackArray.push(10);
stackArray.push(9);
stackArray.push(8);
stackArray.push(7);
//判断是否为满
System.out.println("stackArray is Full: "+stackArray.isFull());
stackArray.push(6);
//判断是否为满
System.out.println("stackArray is Full: "+stackArray.isFull());
//已满报错
stackArray.push(5);
//出栈
for(int j =0; j<5; j++){
System.out.print(" "+stackArray.pop());
}
System.out.println();
//判断是否为空
System.out.println("stackArray is Empty: "+stackArray.isEmpty());
//已空报错
stackArray.pop();
}
}
栈的应用举例
以下两个实例使用的都是同一个栈的类,这里直接给出:
package StackExample;
/**
* 栈应用实例
* @author 磊大大
*/
public class StackX {
private char[] stackArray;
private int maxSize;
private int top;
public StackX(int s){
maxSize = s;
stackArray = new char[maxSize];
top = -1;
}
//入栈
public void push(char ch){
if(!isFull())
stackArray[++top] = ch;
else
System.out.println("Stack is Full");
}
//出栈
public char pop(){
if(!isEmpty())
return stackArray[top--];
else
System.out.println("Stack is Empty");
return 's';
}
//判断是否为空
public boolean isEmpty(){
return top == -1;
}
//判断是否为满
public boolean isFull(){
return top == (maxSize-1);
}
}
-
实例一:单词的逆序输出(控制台输入,之后逆序输出,用栈实现)
原理大家应该都清楚,所以直接给出代码实例:(一)创建一个反转类:
package StackExample;
/**
* 单词反转
* @author 磊大大
*/
public class StackReverser {
private String input;
private String output;
public StackReverser(String in){
input = in;
}
//单词反转函数
public String doRev(){
int stackSize = input.length();
StackX theStack = new StackX(stackSize);
//单词入栈
for(int j =0; j<input.length(); j++){
char ch_in = input.charAt(j);
theStack.push(ch_in);
}
//单词出栈
output = "";
while(!theStack.isEmpty()){
char ch_out = theStack.pop();
output+=ch_out;
}
return output;
}
}
(二)反转实现
package StackExample;
import java.io.*;
/**
* 单词反转测试,从控制台输入单词
* @author 磊大大
*/
public class StackReverserApp {
public static void main(String[] args) throws IOException{
String input,output;
while(true){
System.out.println("Enter a String:");
System.out.flush();
input = getString();
//输入空值结束
if(input.equals(""))
break;
StackReverser theReverser = new StackReverser(input);
output = theReverser.doRev();
System.out.println("Before reverser: "+input);
System.out.println("After reverser: "+output;
}
}
//从控制台输入
public static String getString() throws IOException{
InputStreamReader inr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(inr);
String s = br.readLine();
return s;
}
}
这里JDK自带一个反转方法:
//JDK自带的反转
StringBuilder builder = new StringBuilder(input);
System.out.println("StringBuilder Reverser: "+builder.reverse());
两种方法的结果一致,请自行实现。
- 实例二:括号的检测
在控制台输入一串带有括号的字符,如:a { b [ c ( d ) ] },这里的括号都是成对出现的,括号检测的作用就是检测那个括号不是一对,并提示出来。(有点像我们在编程时,如果少个括号编译不通过,会给出提示,或者和eclipse这些开发软件检测括号是否正确一样);
原理:对于这样一串字符串进行拆分比对,如果等于“{”、“[”、“(”这三种括号,则进行入栈操作,将它们压入栈中;之后继续检测,如果碰到“}”、“]”、“)”中的其中一个,进行一次出栈,并进行比对,如果能够和出栈的凑成一对“{}”、“[]”、“()”,则说明输入正确,否则就报错。在比对完后需要进行栈是否为空检测,若不为空,说明少输入了一个右括号,否则正确;
- 代码实现:
(一)创建括号检测类:
package StackExample;
/**
* 利用栈实现括号检查
* @author 磊大大
*/
public class StackBracket {
private String input;
public StackBracket(String in){
input = in;
}
//括号检查
public void check(){
int stackSize = input.length();
StackX theStack = new StackX(stackSize);
for(int j=0; j<input.length(); j++){
char ch_in = input.charAt(j);
switch(ch_in){
case '{':
case '[':
case '(':
theStack.push(ch_in);
break;
case '}':
case ']':
case ')':
if(!theStack.isEmpty()){
char ch_out = theStack.pop();
if((ch_in == '}' && ch_out!='{') || (ch_in == ']' && ch_out!='[') || (ch_in == ')' && ch_out!='('))
System.out.println("Error: "+ch_in+" at "+j);
}
default:
break;
}
}
//不为空也出错,说明少一个右括号
if(!theStack.isEmpty())
System.out.println("Error: missing right delimiter!");
}
}
(二)检测实现:
package StackExample;
import java.io.BufferedReader;
import java.io.*;
/**
* 括号检查代码测试
* @author 磊大大
*/
public class StackBracketApp {
public static void main(String[] args) throws IOException{
String input,output;
while(true){
System.out.println("Enter string containing delimiters:");
System.out.flush();
input = getString();
if(input.equals(""))
break;
StackBracket theStack = new StackBracket(input);
theStack.check();
}
}
//从控制台输入
public static String getString() throws IOException{
InputStreamReader inr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(inr);
String s = br.readLine();
return s;
}
}
以上就是关于栈的Java实现和应用举例,小伙伴们有没有一种发现了新大陆的感觉?不知道eclipse中的括号检测是不是就是按这样的原则来的呢!
下一篇学习队列的相关知识。