Data Structures and Algorithms - Detailed stack

What is the stack

Here Insert Picture Description
百度百科The stack is so defined:

  • Stack (stack), also known as 堆栈, it is a kind 运算受限of 线性表. Only defined 表尾进行插入and 删除linear operating table. This terminal is referred to 栈顶, relatively, the other end is called 栈底. To insert a new element, also known as the stack 进栈、入栈或压栈, which is a new element into the top element of the above, making the new top of the stack; a stack removes elements from an also known 出栈或退栈, it is to delete the top element, so that adjacent elements becomes the new top of the stack.

A little more about the key terms:

  • Restricted operation : is this table that you can not just delete inserted. Only insertion and deletion in accordance with its rules. For example, the stack would only be at one end of the line insertions and deletions . Similarly, the queue operation is limited, it can only operate in two days.
  • Linear table : Stack also a linear form, linear form through detailed above, it is an expression of logic data . That is, each element in the stack are adjacent. Of course, points on the specific implementation 数组和链表实现, they have different physical storage structure. However, the logical structure ( 实现的目的) the same.
  • Stack bottom of the stack: This description is biased in favor of content on logic, because we know that 数组在末尾插入删除is easier, and 单链表通常在头插入删除easier. So arrays can be done by the end of the top of the stack, and the head of the list can do top of the stack.

Here Insert Picture Description

Stack of applications:

  • Wide stack of applications, such as execution of your program view the call stack, addition and subtraction, even in the search algorithm dfs, replace recursion and so on. So stack also must master a data structure. Many also stack specification, such as books get put on the map as a book!

Design and Introduction

这里我们介绍数组实现的栈和链表实现的栈。

数组实现

结构设计

  • 对于数组来说,我们模拟栈的过程很简单,因为栈是后进先出,我们很容易在数组的末尾进行插入和删除。所以我们选定末尾为栈顶。所以对于一个栈所需要的基础元素是 一个data数组和一个top(int)表示栈顶位置。
  • 那么初始话以及构造的函数代码为:
private T data[];
private int top;
public seqStack() {
	data=(T[]) new Object[10];
	top=-1;
}
public seqStack(int maxsize)
{
	data=(T[]) new Object[maxsize];
	top=-1;
}

push插入

栈的核心操作之一push:入栈操作。

  • 如果top<数组长度-1。入栈。top++;a[top]=value;
  • 如果top==数组长度-1;栈满。
    Here Insert Picture Description

pop弹出并返回首位

  • 如果top>=0,栈不为空,可以弹出。return data[top--];
  • 如下图,本来栈为1,2,3,4(栈顶),执行pop操作。top变为3的位置并且返回4;
    Here Insert Picture Description

其他操作

  • 其他例如peek操作时返回栈顶不弹出.所以只需满足题意时候return data[top]即可。

链表实现

有数组实现,链表当然也能实现。对于栈的运算。大致可以分为两种思路:

  • 像数组那样在尾部插入删除。大家都知道链表效率低在查询。而查询到尾部效率很低。而我们就算用了尾指针,可以解决尾部插入效率。但是依然无法解决删除效率(删除需要找到前节点).还需要双向链表。前面虽然详细介绍过双向链表,但是这样未免太复杂
  • 所以我们采用带头节点的单链表在头部插入删除,把头部当中栈顶,这样精了很多。插入直接在头节点后插入。而删除也直接删除头节点后第一个元素即可。

结构设计

长话短说,短话不说。直接上代码就懂。
链表的节点

static class node<T>
{
	T data;
	node next;
	public node() {    
	}
	public node(T value)
	{
		this.data=value;
	}
}

基本结构:

public class lisStack <T>{
	int length;
    node<T> head;//头节点
    public lisStack() {
		head=new node<>();
		length=0;
	}
	//其他方法
}

push插入

与单链表头插入一致,如果不太了解请先看笔者队线性表介绍的。

和数组形成的栈有个区别。就是理论上栈没有大小限制(不突破内存系统限制)。不需要考虑是否越界。

  • 节点team入栈
  • 空链表入栈head.next=team;
  • 非空入栈team.next=head.next;head.next=team;
    Here Insert Picture Description

pop弹出

与单链表头删除一致,如果不太了解请先看笔者队线性表介绍的。

和数组同样需要判断是否为空。

  • 节点team出栈
  • head指向team后驱节点。不需要考虑链表是否为1个节点。如果为1个节点,team.next=null.执行完毕head.next=null。变为空,满足条件。
    Here Insert Picture Description

其他操作

  • 其他例如peek操作时返回栈顶不弹出.所以只需判空满足题意时候return head.next.data即可。而length你可以遍历链表返回长度,也可以动态设置(本文采取)跟随栈长变化。其他操作直接看api。

实现代码

数组实现

package 队栈;

public class seqStack<T> {
	
	private T data[];
	private int top;
	public seqStack() {
		data=(T[]) new Object[10];
		top=-1;
	}
	public seqStack(int maxsize)
	{
		data=(T[]) new Object[maxsize];
		top=-1;
	}
	boolean isEmpty()
	{
		return top==-1;
	}
	int length()
	{
		return top+1;
	}
	
	boolean push(T value) throws Exception//压入栈
	{
		if(top+1>data.length-1)
		{
			throw new Exception("栈已满");
		}
		else {
			data[++top]=value;
			return true;
		}
	}
	T peek() throws Exception//返回栈顶元素不移除
	{
		if(!isEmpty())
		{
			return data[top];
		}
		else {
			throw new Exception("栈为空");
		}
	}
	T pop() throws Exception
	{
		if(isEmpty())
		{
			throw new Exception("栈为空");
		}
		else {
		   return data[top--];
		}
	}
	public String toString()
	{
		if(top==-1)
		{
			return "";
		}
		else {
			String va="";
			for(int i=top;i>=0;i--)
			{
				va+=data[i]+"  ";
			}
			return va;
		}
	}
}

链表实现

package 队栈;

public class lisStack <T>{
	static class node<T>
	{
		T data;
		node next;
		public node() {    
		}
		public node(T value)
		{
			this.data=value;
		}
	}
	int length;
    node<T> head;//头节点
    public lisStack() {
		head=new node<>();
		length=0;
	}
    boolean isEmpty()
	{
		return head.next==null;
	}
	int length()
	{
		return length;
	}
    public void push(T value) {//近栈
       node<T> team=new node<T>(value);
       if(length==0)
       {
    	   head.next=team;
       }
       else {
		team.next=head.next;
		head.next=team;}
       length++;
    }
    public T peek() throws Exception {
        if(length==0) {throw new Exception("链表为空");}
        else {//删除
			return (T) head.next.data;
		}
  }
    public T pop() throws Exception {//出栈
          if(length==0) {throw new Exception("链表为空");}
          else {//删除
        	T value=(T) head.next.data;
			head.next=head.next.next;//va.next
			length--;
			return value;
			
			
		}
    }
    public String toString(){
    	if(length==0) {return "";}
    	else {
			String va="";
		    node team=head.next;
		    while(team!=null)
		    {
		    	va+=team.data+" ";
		    	team=team.next;
		    }
		    return va;
		}
       
    }
}

测试

Here Insert Picture Description

总结

  • 栈的逻辑比较简单。很容易理解,实现起来也相对容易。但是要注意数组情况的界限问题。
  • 后面将介绍队列,相比栈,队列内容更丰富一些。难度也稍大一些。
  • 如果有不好需要改进还请指出
  • 最后,喜欢的话可以关注公众号:bigsai 持续分享(回复 数据结构 获得精心准备资料一份!)

Here Insert Picture Description

He published 185 original articles · won praise 1706 · Views 510,000 +

Guess you like

Origin blog.csdn.net/qq_40693171/article/details/99322807