4、栈

本文介绍了栈这种特殊的线性表,重点讲解了顺序栈和链栈的实现,包括它们的基本操作如入栈、出栈、判断栈空等。此外,还展示了使用栈进行括号匹配的语法检查以及解决汉诺塔问题的实例。顺序栈通过数组实现,链栈通过链式存储结构实现,两者各有优缺点。栈在计算机科学中有着广泛的应用,例如括号匹配、表达式求值等。
摘要由CSDN通过智能技术生成

4、栈


1、简介

​ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7jbH9WlS-1608815157298)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201216211223243.png)]

栈的模型

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tFUx46P3-1608815157304)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201216211401450.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bVWE6fzI-1608815157307)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201216211614669.png)]

总结:栈的特点 ====>
  1. 栈是一种特殊的线性表,插入和删除操作都在表的尾部进行。 表的尾部 <====> 栈顶

  2. 栈是后进先出的线性表。 打个比方:就像盘子一样,放的时候每次在上面,拿的时候也从上面开始拿。

  3. 栈分为:

    • 顺序栈 ====> 顺序存储结构,通常用数组实现。

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l35xrsJw-1608815157311)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201216213124225.png)]

    • 链栈 ====> 链式存储结构,

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-W4DsrHJG-1608815157317)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201216213041919.png)]

2、栈的抽象数据类型接口

/**
 * @author Administrator
 *			栈的抽象数据类型描述
 */
public interface IStack {
	
	//1、将栈置空
	public void clear();
	//2、判断栈是否为空
	public boolean isEmpty();
	//3、返回栈的元素个数
	public int length();
	//4、返回栈顶元素
	public Object peek();
	//5、将数据元素x入栈
	public void push(Object x);
	//6、将栈顶元素出栈,并返回
	public Object pop();
	//7、输出栈中的所有元素
	public void display();
	
}

3、顺序栈

/**
 * @author Administrator 顺序栈:用数组实现
 */
public class SqStack {
	// 存储空间
	private Object[] stack;
	// 指示栈顶元素的位置,指向栈顶元素存储位置的下一个存储单元位置
	private int top;
	// 栈的最大存储单元个数
	private int max;

	// 构造空栈,存储单元个数为最大
	public SqStack(int max) {
		super();
		this.max = max;
		// 构造栈
		stack = new Object[max];
	}

	// 1、将栈置空: 栈顶为0即可
	public void clear() {
		top = 0;
	}

	// 2、判断栈是否为空
	public boolean isEmpty() {
		return top == 0;
	}

	// 3、返回栈的元素个数
	public int length() {
		return top;
	}

	// 4、返回栈顶元素
	public Object peek() {
		if(! isEmpty())
			return stack[top -1];
		else
			return null;
	}

	// 5、将数据元素x入栈
	public void push(Object x) {
		//判断栈是否已满
		if(top == max) {
			System.out.println("栈满,不能插入!");
		}
		//否则,进行插入至栈顶
		stack[top] = x;
		top++;
	}

	// 6、将栈顶元素出栈,并返回
	public Object pop() {
		//判断栈是否为空
		if(isEmpty()) {
			return "空栈!";
		}
		top--;
		//为啥先减再出栈??
		return stack[top];
		
	}

	// 7、输出栈中的所有元素
	public void display() {
		for (int i = top - 1; i >= 0; i--) {
			System.out.print(stack[i]+"<===");
		}
	}

}

测试:

public class SqStackTest {

	public static void main(String[] args) {

		SqStack sqStack = new SqStack(5);

		// 1、判断栈是否为空
		System.out.println(sqStack.isEmpty());
		// 2、返回栈的元素个数
		System.out.println(sqStack.length());
		// 3、将数据元素x入栈
		sqStack.push("徐凤年");
		sqStack.push("青鸟");
		sqStack.push("红麝");
		sqStack.push("姜泥");
		sqStack.push("洛阳");
		// 4、判断栈是否为空
		System.out.println(sqStack.isEmpty());
		// 5、返回栈的元素个数
		System.out.println(sqStack.length());
		//6、再次入栈
		//sqStack.push("陈芝豹");
		
		//7、将栈顶元素出栈,并返回
		System.out.println(sqStack.pop());
		
		//8、输出栈中的所有元素
		sqStack.display();

	}

}

实例:实现括号匹配的语法检查

/**
 * @author Administrator
 *			利用顺序栈实现括号匹配
 */
public class CheckBrackets {
	
	// 存储空间
		private Object[] stack;
		// 指示栈顶元素的位置,指向栈顶元素存储位置的下一个存储单元位置
		private int top;
		// 栈的最大存储单元个数
		private int max;

		// 构造空栈,存储单元个数为最大
		public CheckBrackets(int max) {
			super();
			this.max = max;
			// 构造栈
			stack = new Object[max];
		}

		// 2、判断栈是否为空
		public boolean isEmpty() {
			return top == 0;
		}

		public void push(Object x) {
			//判断栈是否已满
			if(top == max) {
				System.out.println("栈满,不能插入!");
			}
			//否则,进行插入至栈顶
			stack[top] = x;
			top++;
		}

		// 6、将栈顶元素出栈,并返回
		public Object pop() {
			//判断栈是否为空
			if(isEmpty()) {
				return "空栈!";
			}
			top--;
			//为啥先减再出栈??
			return stack[top];
			
		}
		
	//创建方法
	public void isMatched(String str) {
		
		//只要遍历出左括号,就入栈
		for (int i = 0; i < str.length(); i++) {
			//左括号入栈
			if (str.charAt(i) == '(') {
				push('(');
			}
			else if (str.charAt(i) == ')' && ! isEmpty()) {
				pop();
			}
			else if (str.charAt(i) == ')' &&  isEmpty()) {
				System.out.println("括号不匹配!");
				return ;
			}
		}
		if (isEmpty()) {
			System.out.println("配对完毕,括号匹配!");
		}
		else {
			System.out.println("括号不匹配!");
		}
	}


	
	public static void main(String[] args) {
		String string1 = "(a+b*(c+d))";
		String string2 = "(a+b*(c+d)))";
		
		CheckBrackets checkBrackets1 = new CheckBrackets(string1.length());
		checkBrackets1.isMatched(string1);
		
		CheckBrackets checkBrackets2 = new CheckBrackets(string2.length());
		checkBrackets2.isMatched(string2);
		
	}
		
}

4、链栈

引入结点类:

package linkedList;
/**
 * @author Administrator
 *		结点类
 */
public class Node {
	//1、定义数据域,存放结点数据值
	public Object data;
	//2、定义指针域,存放后继结点
	public Node next;
	
	//无参构造函数
	public Node() {
		
	}

	//有参构造函数
	public Node(Object data, Node next) {
		super();
		this.data = data;
		this.next = next;
	}

	public Node(Object data) {
		super();
		this.data = data;
	}
	
}

链栈实现类:

package stack;

import linkedList.*;

/**
 * @author Administrator
 *			链栈
 */
public class LinkedStack {
	
	//创建栈顶元素top
	private Node top; 
	
	
	// 1、将栈置空: 栈顶为0即可
		public void clear() {
			top = null;
		}

		// 2、判断栈是否为空
		public boolean isEmpty() {
			return top == null;
		}

		// 3、返回栈的元素个数
		public int length() {
			Node p = top;
			int length = 0;
			while (p != null) {
				p = p.next;
				length++;
			}
			return length;
		}

		// 4、返回栈顶元素
		public Object peek() {
			if(! isEmpty())
				return top.data;
			else
				return null;
		}

		// 5、将数据元素x入栈
		public void push(Object x) {
			Node s = new Node(x);
			s.next = top;
			top = s;
			
		}

		// 6、将栈顶元素出栈,并返回
		public Object pop() {
			if (isEmpty()) {
				return null;
			}
			Node p = top;
			top = top.next;
			return p.data;
		}

		// 7、输出栈中的所有元素
		public void display() {
			Node p = top;
			while (p != null) {
				System.out.println(p.data+"===>");
				p = p.next;
			}
		}
	
}

测试类:

package stack;

public class LinkedStackTest {

	public static void main(String[] args) {
		
		LinkedStack linkedStack = new LinkedStack();
		
		System.out.println(linkedStack.isEmpty());
		System.out.println(linkedStack.length());
		
		linkedStack.push("徐凤年");
		linkedStack.push("青鸟");
		linkedStack.push("红麝");
		linkedStack.push("姜泥");
		
		System.out.println(linkedStack.isEmpty());
		System.out.println(linkedStack.length());
		
		System.out.println(linkedStack.pop());
		System.out.println(linkedStack.peek());

	}

实例:解决汉诺塔问题

package stack;
/**
 * @author Administrator
 *			编程汉诺塔问题
 */
public class Hanoi {

	public static void main(String[] args) {
		hanoi(1, 'x', 'y','z');
		System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *");
		hanoi(3, 'x','y', 'z');
	}
	//解决汉诺塔方法
	public static void hanoi(int n , char x , char y , char z) {
		if(n == 1)
			move(1,x,z);
		else {
			hanoi(n-1, x, z, y);
			move(n, x, z);
			hanoi(n-1, y, x, z);
		}
	}
	
	//移动的方法
	private static void move(int i, char x, char z) {
		System.out.println("将圆盘==>"+i+"从塔座"+x+"移动到塔座"+z+"    ");
		
	}

}

t.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *");
hanoi(3, ‘x’,‘y’, ‘z’);
}
//解决汉诺塔方法
public static void hanoi(int n , char x , char y , char z) {
if(n == 1)
move(1,x,z);
else {
hanoi(n-1, x, z, y);
move(n, x, z);
hanoi(n-1, y, x, z);
}
}

//移动的方法
private static void move(int i, char x, char z) {
	System.out.println("将圆盘==>"+i+"从塔座"+x+"移动到塔座"+z+"    ");
	
}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值