3.1 栈结构实现

  1. 栈是一个先入后出的有序列表。
  2. 栈中元素的添加与删除都发生在线性表的同一端,允许插入和删除的一端被称为栈顶,另一端被称为栈底。
  3. 最先入栈的元素在栈底,最后入栈的元素在栈顶。最先删除的元素为最后入栈的元素,最后删除的元素为最先入栈的元素。

数组实现栈结构

  1. 主要是想push()和pop()两个方法,栈顶位于数组尾部,使用top来定位到栈顶(数组尾)
  2. 代码
import java.util.Scanner;

/**
 * 实现栈,并测试其功能
 * @author dxt
 *
 */
public class ArrayStackDemo {
	public static void main(String[] args) {
		//测试栈的实现
		ArrayStack stack = new ArrayStack(5);
		char command = ' ';
		boolean loop = true;
		Scanner scan = new Scanner(System.in);
		while(loop) {
			System.out.println("向栈中添加元素:a");
			System.out.println("从栈中取出元素:g");
			System.out.println("打印栈中元素:p");
			System.out.println("退出程序:e");
			System.out.println("请输入命令:");
			command = scan.next().charAt(0);
			switch (command) {
			case 'a':
				System.out.println("请输入添加的数据:");
				int value = scan.nextInt();
				stack.push(value);
				break;
			case 'g':
				try {
					int num = stack.pop();
					System.out.println(num);
				}catch(Exception e) {
					System.out.println(e.getMessage());
				}
				break;
			case 'p':
				stack.printStack();
				break;
			case 'e':
				scan.close();
				loop = false;
				break;
			default:
				break;
			}
		}
		System.out.println("退出程序。");
	}
}

class ArrayStack{
	private int size;	//栈的大小
	private int[] stack;	//使用一个数组来模拟栈
	private int top = -1;	//top表示栈顶,初始为-1,top同样展示了栈中的元素个数
	
	//构造器
	public ArrayStack(int size) {
		this.size = size;
		stack = new int[this.size];
	}
	//判断栈是否已满
	public boolean isFull() {
		return top == (size-1);
	}
	//判断栈是否为空
	public boolean isEmpty() {
		return top == -1;
	}
	//入栈操作,将数据压入栈顶
	public void push(int value) {
		//1.判断站是否已满
		if(isFull()) {
			System.out.println("栈已满,添加失败。");
			return;
		}
		//2. 栈顶后移,然后入栈
		top++;
		stack[top] = value;
	}
	//出栈操作,将栈顶数据取出
	public int pop() {
		//1. 判断栈是否为空
		if(isEmpty()) {
			throw new RuntimeException("栈为空,出栈失败。");
		}
		//2. 出栈,栈顶减一
		int value = stack[top];
		top--;
		return value;
	}
	//遍历输出栈,从栈顶向栈底遍历
	public void printStack() {
		if(isEmpty()) {
			System.out.println("栈空,没有数据。");
			return;
		}
		for(int i=top; i>=0; i--) {
			System.out.println(stack[i]);
		}
	}
}

单链表实现栈结构

  1. 实现的栈的主要功能有:push()、pop()、打印、获取栈中元素个数。
  2. 代码
import java.util.Scanner;

/**
 * 使用单链表实现栈
 * @author dxt
 *
 */
public class ListStackDemo {
	public static void main(String[] args) {
		//测试栈的实现
		ListStack stack = new ListStack();
		char command = ' ';
		boolean loop = true;
		Scanner scan = new Scanner(System.in);
		while(loop) {
			System.out.println("向栈中添加元素:a");
			System.out.println("从栈中取出元素:g");
			System.out.println("打印栈中元素:p");
			System.out.println("获取元素个数:s");
			System.out.println("退出程序:e");
			System.out.println("请输入命令:");
			command = scan.next().charAt(0);
			switch (command) {
			case 'a':
				System.out.println("请输入添加的数据:");
				int value = scan.nextInt();
				stack.push(value);
				break;
			case 'g':
				try {
					int num = stack.pop();
					System.out.println(num);
				}catch(Exception e) {
					System.out.println(e.getMessage());
				}
				break;
			case 'p':
				stack.printStack();
				break;
			case 's':
				System.out.println("栈中元素个数:" + stack.getSize());
				break;
			case 'e':
				scan.close();
				loop = false;
				break;
			default:
				break;
			}
		}
		System.out.println("退出程序。");		
	}
}
/**
 * 节点类
 * @author dxt
 *
 */
class Node{
	private int num;	//数据域
	private Node next;	//next域
	//构造器
	public Node(int num) {
		this.num = num;
	}
	//javabean
	public void setNum(int n) {
		this.num = n;
	}
	public int getNum() {
		return this.num;
	}
	public void setNext(Node node) {
		this.next = node;
	}
	public Node getNext() {
		return this.next;
	}
}
/**
 * 用于实现栈的单链表,栈的主要功能:push() 和  pop()
 * 两个主要功能都发生在 栈顶,且如果想要打印栈中内容,也是从 栈顶 开始打印
 * 将 头节点 指向的第一个数据节点 作为栈顶  要比链表尾作为 栈顶 更加合适 
 * @author dxt
 *
 */
class SingleLinkedList{
	private Node head = new Node(0);	//头节点
	
	//判断链表是否为空
	public boolean isEmpty() {
		return head.getNext() == null;
	}
	//向头节点后插入节点
	public void addToHead(Node node) {
		node.setNext(head.getNext());
		head.setNext(node);
	}
	//从头 删除第一个数据节点
	public Node deleteFromHead() {
		if(isEmpty()) {
			return null;	//目标是实现栈,所以在链表类中尽量不要有输出,交给栈的实现类去处理
		}
		Node temp = head.getNext();	//保存第一个数据节点
		head.setNext(head.getNext().getNext());	//从链表中删除第一个数据节点
		return temp;
	}
	//从第一个数据节点开始打印数据
	public void printList() {
		//1 判断链表是否为空,虽然在这里进行了判断,但在栈的实现中 不要让程序输出下面判断为空时的语句
		if(isEmpty()) {
			System.out.println("没有数据可以打印");
			return;
		}
		//2. 遍历打印
		Node temp = head.getNext();
		while(temp != null) {
			System.out.println(temp.getNum());
			temp = temp.getNext();	//后移
		}
	}
	//获取链表中节点个数
	public int getLength() {
		//1. 先判断链表是否为空
		if(isEmpty()) {
			return 0;
		}
		//2. 开始计数链表中的节点个数
		int len = 0;
		Node temp = head.getNext();
		while(temp != null) {
			len++;
			temp = temp.getNext();
		}
		return len;
	}
}
/**
 * 使用单链表数据结构实现栈结构
 * @author dxt
 *
 */
class ListStack{
	private SingleLinkedList sll = new SingleLinkedList();
	
	//向栈中添加数据
	public void push(int num) {
		//1 依据数据构建节点
		Node node = new Node(num);
		sll.addToHead(node);
	}
	//从栈中取出数据
	public int pop() {
		//获取要删除的节点,并删除此节点
		Node node = sll.deleteFromHead();
		if(node == null) {
			throw new RuntimeException("栈为空,没有数据。");
		}
		return node.getNum();	//返回节点中的数据
	}
	//打印栈中数据
	public void printStack() {
		//1. 避免在栈打印时 输出 链表打印方法中 判断链表为空时的语句
		if(sll.isEmpty()) {
			System.out.println("栈已空。");
			return;
		}
		//2. 从栈顶打印元素
		sll.printList();
	}
	//获取栈中节点个数
	public int getSize() {
		return sll.getLength();
	}
}

总结

  1. 使用 数组 和 链表 都可以实现栈结构。
    数组:便于查询
    链表:便于删除
    栈:只在一端有数据的修改
  2. 显然可以使用多种结构(单链表、环形链表)实现栈结构,每种的实现方式也不同。一开始我打算使用 双向环形链表 实现栈结构,栈顶在双向环形链表的尾部,双向环形可以方便定位到栈顶,但显然是我把问题想复杂了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值