Java基础--基于链表实现栈

栈是一种基本数据结构,后进先出,对栈的操作都是在栈顶进行的,值得我们去学习,有很多算法问题都能用栈来实现,如LeetCode里面的括号问题的匹配就能用栈来实现。本文是基于上篇文章说的链表进行栈的实现

定义的栈的接口

public interface Stack<T> {
	//获取栈中的元素个数
	int getSize();
	//判断栈是否为空
	boolean isEmpty();
	//入栈
	void push(T ele);
	//出栈并返回栈顶元素
	T pop();
	//栈顶指针指向的元素
	T peek();
}

链表的定义和操作

这里的链表使用了虚拟头结点的方式来实现,这样比较方便进行操作,而且栈的操作:入栈和出栈都是在栈顶进行的,栈顶也对应链表中的头结点。此处的链表操作都是基于索引来进行操作。
package LinkedList;

public class DummyLinked<T> {
	private class Node{
		private T ele;
		private Node next;
		public Node(T t,Node next) {
			this.ele = t;
			this.next = next;
		}
		public Node(T t){
			this(t,null);
		}
	}
	private int size;     //链表元素个数
	private Node dummy;	  //链表的虚拟头结点
	public DummyLinked(){
		dummy = new Node(null,null);
		this.size = 0;
	}
	//获取链表元素的个数
	public int getSize(){
		return this.size;
	}
	//判断链表是否为空
	public boolean isEmpty(){
		return this.size == 0;
	}
	//向链表中间插入元素
	public void add(T ele,int index){
		if (index <0 || index >size){
			throw new IllegalArgumentException("index is error");
		}
			
		Node preNode = this.dummy;
		//找到要插入节点的前一个节点
		for(int i = 0; i < index; i++){
			preNode = preNode.next;
		}
		Node node = new Node(ele);
		//要插入的节点的下一个节点指向preNode节点的下一个节点
		node.next = preNode.next;
		//preNode的下一个节点指向要插入节点node
		preNode.next = node;
		this.size++;
			
	}
	//链表头部添加元素
	public void addFirst(T ele){
		this.add(ele, 0);
	}
	//向链表尾部插入元素
	public void addLast(T ele){
		this.add(ele, this.size);
	}
	//获取链表index位置的元素
	public T get(int index){
		if (index < 0 || index >= this.size){
			throw new IllegalArgumentException("index is error");
		}
		Node node = this.dummy.next;
		for(int i=0; i < index; i++){
			node = node.next;
		}
		return node.ele;
	}
	//获取链表的第一个元素
	public T getFirst(){
		return this.get(0);
	}
	//获取链表最后一个元素
	public T getLast(){
		return this.get(this.size-1);
	}
	//修改链表第index位置上的元素
	public void set(T ele, int index){
		if (index < 0 || index >= this.size){
			throw new IllegalArgumentException("set index is error");
		}
		Node node = this.dummy.next;
		for(int i = 0; i < index; i++){
			node = node.next;
		}
		node.ele = ele;
	}
	//判断链表是否包含某元素
	public boolean isContain(T ele){
		Node cur = this.dummy.next;
		while(cur != null){
			if (cur.ele.equals(ele)){
				return true;
			}
			cur = cur.next;
		}
		return false;
	}
		
	//删除链表index位置上的元素,并且返回删除元素
	public T remove(int index){
		Node pre = this.dummy;
		for (int i = 0; i < index; i++){
			pre = pre.next;
		}
		Node delNode = pre.next;
		pre.next = delNode.next;
		delNode.next = null;
		this.size--;
		return delNode.ele;
	}
	//删除链表的第一个元素
	public T removeFirst(){
		return this.remove(0);
	}
	//删除链表的最后一个元素
	public T removeLast(){
		return this.remove(this.size-1);
	}
	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		Node cur = this.dummy.next;
		while (cur != null){
			sb.append(cur.ele+"->");
			cur = cur.next;
		}
		sb.append("NULL");
		return sb.toString();
	}
}

栈的实现

实现定义好的栈的接口,并且实现该接口相关的方法就可以了。

栈的元素个数&&栈的判空操作

要获取栈中的元素个数,只需要调用链表中的getSize()方法就能很快的获取到了,判空操作也是直接调用链表的判空isEmpty()方法即可,大大简化了在实现栈这方面的操作。
@Override
	public int getSize() {
		return this.dummy.getSize();
	}
	@Override
	public boolean isEmpty() {
		return this.dummy.isEmpty();
	}

入栈&&出栈&&栈顶元素

入栈和出栈都是在栈顶实现的,也是在链表的头结点进行操做,我们只需要调用链表的addFirst()和removeFirst()方法就可以了,获取栈顶元素也是直接调用链表的getFirst()方法就好,时间复杂度都是O(1)。
@Override
	public void push(T ele) {
		this.dummy.addFirst(ele);
	}
	@Override
	public T pop() {
		return  dummy.removeFirst();
	}
	@Override
	public T peek() {
		return this.dummy.getFirst();
	}

为了方便我们测试的时候能够清晰的看到效果,复写了toString方法

@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append("stack top:");
		sb.append(this.dummy);
		return sb.toString();
	}

代码测试

public static void main(String[] args) {
		LinkedStack<Integer> stack = new LinkedStack<Integer>();
		for (int i =0; i < 5; i++){
			stack.push(i);
		}
		System.out.println(stack);
		System.out.println("栈顶元素:"+stack.pop());
		System.out.println(stack);
		System.out.println("栈顶元素:"+stack.peek());
		
	}
结果如下:
stack top:4->3->2->1->0->NULL
栈顶元素:4
stack top:3->2->1->0->NULL
栈顶元素:3

总结:这部分的实现比较简单,主要部分还是链表方面的熟悉度,熟练了链表这个也不成什么问题了(如上述有错的话,希望dalao改正)。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值