栈的基本定义,以及用java实现数组栈和链栈

  • 栈的几个常用的应用场景:

(1)子程序的调用:在跳往某个子程序,会先将该程序(非跳往的子程序)下条指令的地址存放在堆栈中,直到子程序执行完毕,然后从堆栈中将地址取出,恢复原来程序的执行现场;

(2)处理递归调用:和子程序的调用相似,只是除了要存放下一条指令的地址,还要将参数、区域变量等数据存入堆栈中。

(3)表达式的转换(尤其是“ 中缀表达式 转 后缀表达式 ”)及求值。这个是面试的高频知识点。

(4)其他数据结构的算法,如二叉树的遍历、图的深度优先搜索DFS等。


  • 数组栈的定义与基本操作:

定义一个ArrayStack类表示数组栈:

(1)、因为是数组栈, 因此需要定义3个基本属性:

1、栈的最大容量:maxSize ;

2、数组实体: int[ ] stack ;  

3、栈顶指针:int top = -1 ;

(2)、判断栈空:top == -1 ; 判断栈满:top == maxSize - 1;   

(3)、入栈要先判断栈是否满,出栈要判断栈是否空,这是定义方法的临界条件

(4)、遍历数组栈,直接采用for循环,且只能从栈顶(top)自顶向下进行定义。

具体代码如下:

//定义一个ArrayStack 表示栈
class ArrayStack {
	private int maxSize ; //栈的最大容量
	private int[] stack ; //数组模拟栈,数据放在该数组中
	private int top = -1 ;
	//构造器
	public ArrayStack(int maxSize){
		this.maxSize = maxSize;
		stack = new int[this.maxSize] ; 
	}
	
	//判断栈满
	public boolean isFull(){
		return top == maxSize - 1 ;
	}
	//判断栈空
	public boolean isEmpty(){
		return top == -1 ;
	}
	
	//入栈
	public void push(int value){
		//入栈前先判断栈是否满
		if(isFull()) {
			System.out.println("栈满!");
			return ;
		}
		top ++ ;
		stack[top] = value ;
	}
	
	//出栈
	public int pop(){
		//出栈前,先判断栈是否空
		if(isEmpty()){
			//由于必须要返回值,所以用抛出异常来处理
			throw new RuntimeException("栈空,没有数据~");
		}
		int value = stack[top];
		top -- ;
		return value ;
	}
	
	//栈的遍历(只能从栈顶往下遍历)
	public void list(){
		if(isEmpty()){
			System.out.println("没有数据,无法遍历");
			return ;
		}
		for(int i = top ; i >= 0 ; i --){
			System.out.printf("stack[%d] = %d\n" , i , stack[i] );
		}
	}
	
	
}

main函数测试代码:

public class ArrayStackDemo {

	public static void main(String[] args) {
		//测试数组栈是否正确
		ArrayStack stack = new ArrayStack(4) ; 
		String Key = "";
		boolean loop = true ; //控制是否退出菜单
		Scanner scanner = new Scanner(System.in);
		//扫描器,检测键盘输入的数据
		while(loop){
			System.out.println("show: 表示显示栈");
			System.out.println("exit: 退出程序");
			System.out.println("push: 添加数据到栈(入栈)");
			System.out.println("pop: 从栈取出数据(出栈)");
			System.out.println("请输入你的选择:");
			Key = scanner.next() ; 
			switch (Key) {
			case "show":
				stack.list();
				break;
			case "push":
				System.out.println("请输入一个数:");
				int value = scanner.nextInt() ;
				stack.push(value);
				break;
			case "pop":
				try {
					int res = stack.pop();
					System.out.printf("出栈数据为:%d \n",res);
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
				break;
			case "exit":
				scanner.close();
				loop = false ; 
				break;
			}
		}
		System.out.println("程序退出!");
	}

}

 

  • 链栈的定义与基本操作

用链表实现,首先要定义一个节点类SNode

class SNode{
	int no ; //节点编号,是节点排序的依据
	SNode next ; 	
 //构造方法
	public SNode(int no){
		this.no = no ; 
	}
	@Override
 //为了输出格式更清楚,在此重写toString方法
	public String toString() {
		return "SNode [no=" + no + "]";
	}	
}

然后定义链栈类LinkedStack

(1)结合栈和链表的性质,需要定义三个基本属性:

1、头节点top,同时充当栈顶指针;

2、栈的容量: int maxSize ; 

3、栈中当前元素个数:int count = 0 ;

(2)栈空与栈满的条件用count来定义;

(3)push()与pop()均在链表头部进行:push对应插入节点、pop对应删除节点;

具体代码实现如下:

class LinkedStack{
	private SNode top = new SNode(-1);//表示栈顶
	private int maxSize = 3 ; //假定栈的最大空间为3
	private int count = 0 ; 	//声明栈的元素个数
	
    //判断栈满
	public boolean isFull(){
		return count == maxSize ;
	}
    //判断栈空
	public boolean isEmpty(){
		return count == 0 ;
	}

    //入栈操作
	public void push(int value){
		if(isFull()){
			System.out.println("栈满,不能插入栈中");
			return ;
		}
		//push用带头结点的链表使用头插法实现
		SNode temp = new SNode(value);
		temp.next = top.next;
		top.next = temp ;
		count ++ ;
	}

    //出栈操作
	public int pop(){
		if(isEmpty()){
			throw new RuntimeException("栈空,没有数据可出");
		}
		//pop操作借助top指针实现
		SNode temp = top.next ;
		top.next = temp.next ;
		count -- ;
		return temp.no;
	}
	
    //显示栈中元素
	public void list(){
		if(isEmpty()){
			System.out.println("没有数据,无法遍历");
			return ;
		}
		SNode temp = top.next;
		while(temp!=null){
			System.out.println(" " + temp.no);
			temp = temp.next ;
		}
	}
}

main函数及测试代码:

public class LinkedStackDemo {
	//链栈的代码实现
	public static void main(String[] args) {
		//用链表模拟栈
		LinkedStack linkedStack = new LinkedStack();
		String Key = "";
		boolean loop = true ; 
		Scanner scanner = new Scanner(System.in);
		//扫描器,检测键盘输入的数据
		while(loop){
			System.out.println("show: 表示显示栈");
			System.out.println("exit: 退出程序");
			System.out.println("push: 添加数据到栈(入栈)");
			System.out.println("pop: 从栈取出数据(出栈)");
			System.out.println("请输入你的选择:");
			Key = scanner.next() ; 
			switch (Key) {
			case "show":
				linkedStack.list();
				break;
			case "push":
				System.out.println("请输入一个数:");
				int value = scanner.nextInt() ;
				linkedStack.push(value);
				break;
			case "pop":
				try {
					int res = linkedStack.pop();
					System.out.printf("出栈数据为:%d \n",res);
				} catch (Exception e) {
					System.out.println(e.getMessage());
				}
				break;
			case "exit":
				scanner.close();
				loop = false ; 
				break;
			}
		}
		System.out.println("程序退出!");
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值