2.2 栈

栈是什么

​ 栈是一种特殊的线性表。栈与线性表的不同,体现在增和删的操作。具体而言,栈的数据结点必须后进先出。后进的意思是,栈的数据新增操作只能在末端进行,不允许在栈的中间某个结点后新增数据。先出的意思是,栈的数据删除操作也只能在末端进行,不允许在栈的中间某个结点后删除数据。

​ 也就是说,栈的数据新增和删除操作只能在这个线性表的表尾进行,即在线性表的基础上加了限制。

栈的基本操作

  • 新增:通常也叫作 push压栈
  • 删除:通常也叫作 pop出栈

顺序栈

​ 栈的顺序存储可以借助数组来实现。一般来说,会把数组的首元素存在栈底,最后一个元素放在栈顶。然后定义一个 top 指针来指示栈顶元素在数组中的位置。假设栈中只有一个数据元素,则 top = 0。一般以 top 是否为 -1 来判定是否为空栈。当定义了栈的最大容量为 StackSize 时,则栈顶 top 必须小于 StackSize。

链栈

​ 关于链式栈,就是用链表的方式对栈的表示。通常,可以把栈顶放在单链表的头部,如下图所示。由于链栈的后进先出,原来的头指针就显得毫无作用了。因此,对于链栈来说,是不需要头指针的。相反,它需要增加指向栈顶的 top 指针,这是压栈和出栈操作的重要支持。

案例

1.匹配括号

给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。有效字符串需满足:左括号必须与相同类型的右括号匹配,左括号必须以正确的顺序匹配。例如,{ [ ( ) ( ) ] } 是合法的,而 { ( [ ) ] } 是非法的

解:

核心思路: 即将入栈的和栈顶的配对,如果能配上就取出栈顶的,直到栈为空,返回"合法" ,如果匹配不上,就返回"非法"

import java.util.Stack;

public class StackTest {

	public static void main(String[] args) {
		
		String s ="{[(([))]}";
		System.out.println(isOk(s));
		
	}

	private static String isOk(String s) {
		
		Stack stack = new Stack();
		
		for(int i = 0;i < s.length(); i++) {
			char curr = s.charAt(i);
			
			//判断是否是左侧的括号,是的话就入栈
			if(isLeft(curr)) {
				stack.push(curr);
			}else {
				//如果是空的 表示第一个就是右括号,所以直接非法
				if(stack.isEmpty()) {
					return "非法";
				}
				
				//取出栈顶那个 判断与当前的符号是否配对
				char top = (char)stack.pop();
				
				if(!isPair(top,curr)) {
					return "非法";
				}
			}	
		}
		if(stack.isEmpty()) {
			return "合法";
		}
		
		return "非法";
	}
	
	private static Boolean isLeft(char c) {	
		
		return c=='{'||c=='['||c=='(';
	
	}
	
	private static Boolean isPair(char top ,char pop) {
	
		return top=='{'&&pop =='}'||top=='('&&pop ==')'||top=='['&&pop ==']';
	}

}

2.翻转

给定一个包含 n 个元素的链表,现在要求每 k 个节点一组进行翻转,打印翻转后的链表结果。其中,k 是一个正整数,且 n 可被 k 整除,

例如,链表为 1 -> 2 -> 3 -> 4 -> 5 -> 6,k = 3,则打印 321654。我们试试用栈来解决它吧。

import java.util.Stack;

public class StackTest2 {

	public static void main(String[] args) {

		String s = "123456";

		reverse(s, 3);

	}

	/**
	 * 将字符串 按照每k个一组翻转 利用了栈 后进先出的原理
	 * 
	 * @param s
	 * @param k
	 */
	private static void reverse(String s, int k) {

		Stack<Character> stack = new Stack<Character>();

		for (int i = 0; i < s.length(); i++) {

			char element = s.charAt(i);
			stack.push(element);

			if (stack.size() >= k) {

				while (!stack.isEmpty()) {
					char c = (char) stack.pop();
					System.out.print(c);
				}

			}

		}
	}

}

posted @ 2020-10-23 11:13  Nixon  阅读(114)  评论(0编辑  收藏  举报