详解数据结构中栈的定义和操作

Posted 华为云开发者社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了详解数据结构中栈的定义和操作相关的知识,希望对你有一定的参考价值。

摘要:本文为大家详解数据结构中栈的定义和操作。

本文分享自华为云社区《数据结构:详细讲解栈的定义、栈的操作》,作者: 高彬滔 。

1.栈的定义

栈(stack):是只允许在一端进行插入或者删除操作的线性表(即后进先出,大概可以理解为吃饱了吐出来)

  • 空栈:不含元素的空标配
  • 栈顶:表尾端
  • 栈底:表头端
  • 进栈顺序:a1->a2->a3->a4->a5
  • 出栈顺序:a5->a4-a3->a2->a1

2.对比线性表和栈基本操作

2.1 线性表的基本操作

  • InitList(&L):初始化表。构造一个空的线性表L,分配内存空间
  • DestoryList(&L):销毁操作。销毁线性表,并且释放线性表L所占用的空间
  • ListInsert(&L,i,e):插入操作,在表L中的第i个位置上插入指定元素e
  • ListDelete(&L,i,e):删除操作,删除表L中的第i个位置的元素,并且用e返回删除元素的值
  • LocateElem(L,e):按值查找操作,在表L中查找具有给定关键字值的元素
  • GetElem(L,i):按位查找操作,获取表L中第i个位置的元素的值

2.2 栈的基本操作

  • InitStack(&S):初始化栈,构造一个空栈S,分配内存空间
  • DestoryStack(&S):销毁栈,销毁并释放栈S所占用的内存空间
  • Push(&S,x):进栈,若栈S未满,则将x加入使之成为新的栈顶
  • Pop(&S,&x):出栈,若栈S非空,则弹出栈顶元素,并用x返回
  • GetTop(S,&x):读栈顶元素,若栈S非空,则用x返回栈顶元素

其他常见操作: StackEmpty(S):判断一个栈S是否为空,若S为空,则返回true,否则返回false

3.顺序栈

3.1顺序栈的定义

#define MaxSize 10           //定义栈中元素的最大个数 
typedef struct
 ElemType data[MaxSize];   //静态数组存放栈中的元素
    int top;      //栈顶指针
SqStack;         //结构体重命名

声明一个顺序栈后就会在内存中分配一整片连续的空间,其中内存大小为:MaxSize*sizeof(ELemType)

void testStack()
 SqStack S; //声明一个顺序栈

3.2栈的初始化操作

由于栈顶指针top需要指向此时栈顶元素,所以让top指向0是不合理的,可以初始化让top指向-1;判断一个栈是否为空,即判断S.top是否等于-1

初始化栈:

void Inittack(SqStack)
 SqStack S;   //声明一个顺序栈
 S.top=-1;

判断栈空:

bool StackEmpty(SqStack S)
    if(S.top==-1)      //栈空
        return true;
    else 
        return false;  //非空

3.3进栈操作

分析:

  1. 判断栈是否为空
  2. 栈顶指针+1
  3. 新元素入栈
bool Push(SqStack &S,ElemType x)
 if(S.top==NaxSize-1)
        return false;
 S.top+=1;
 S.data[S.top]=x;
        return true;

3.4出栈操作

bool Push(SqStack &S,ElemType &x)
 if(S.top==-1)
        return false;
    x=S.data[S.top--];
        return true;

3.5读栈顶元素操作

bool GetTop(SqStack &S,ElemType &x)
 if(S.top==-1)
        return false;
    x=S.data[S.top];
        return true;

4.共享栈

两个栈共享同一片空间

#define MaxSize 10           //定义栈中元素的最大个数 
typedef struct
 ElemType data[MaxSize];   //静态数组存放栈中的元素
    int top0;     //0号栈栈顶指针
    int top1;     //1号栈栈顶指针
SqStack;         //结构体重命名
初始化栈:
void InitStack(ShStack &S)
 S.top0=-1;
 S.top1=MaxSize;

5.链栈的定义

  • 进栈/出栈都只能在栈顶一段进行
  • 链头作为栈顶
typedef struct Linknode
 ElemType data;           //数据域
    struct Linknode *next;   //指针域
*LiStack                    //栈类型定义

 

点击关注,第一时间了解华为云新鲜技术~

数据结构基础 栈的详解

一.栈的定义

栈(stack)是一种特殊的线性表,是一种只允许在表的一端进行插入或删除操作的线性表。表中允许进行插入和删除操作的一端称为栈顶,最下面的那一端称为栈底。栈顶是动态的,它由一个称为栈顶指针的位置指示器指示。当栈中没有数据元素时,称之为空栈。栈的插入操作也称为进栈或入栈,栈的删除操作称为出栈或退栈。

栈的特点是先进后出

二.栈的基本操作

初始栈:创建一个空栈
入栈:在栈顶添加一个数据元素
出栈:删除栈顶数据元素
取栈顶元素:获取栈中当前栈顶的数据元素,栈中数据元素不变
求栈长度:获取栈中的数据元素个数
判断栈空:判断栈中是否有数据元素

三.栈的抽象数据类型

ADT 栈(stack)
数据元素 可以是任意类型,只要同属一个数据对象即可;
数据关系 数据元素之间呈线性关系,假设栈中有n个元素(a1, a2,a3,…,an),则对
每一个元素ai(i=1,2,…,n-1)都存在关系(ai,ai+1),并且a1无前趋,an无后继。
数据操作 将对栈的基本操作定义在接口IStack中,代码如下:

public interface IStack<E> 
E push(E item);//入栈
E pop(); //出栈
E peek(); //取栈顶元素
int size(); //求栈的长度
void clear();//清空栈
boolean isEmpty(); //判断栈是否为空

四.用顺序栈实现栈

1.顺序栈的存储结构:
用一片连续的存储空间来存储栈中的数据元素,这样的栈称为顺序栈(sequence stack)。
栈顶指示器top设在数组第一个元素前面的位置,top随着插入和删除而变化,当栈为空时,top=-1
2.实现顺序栈的接口

public interface IStack<E>
    E push(E e); //入栈
    E pop(); //出栈
    E peek();//取栈顶元素
    boolean isEmpty();//判断栈是否为空
    int size();//栈的尺寸
    void clear();//清空栈

3.实现顺序栈

public class SeqStack<E> implements IStack<E>
    private int maxsize;  //栈的最大容量
    private int top;  //栈顶指针
    private Object arr[];

    public SeqStack(int maxsize)
        arr = new Object[maxsize];
        this.maxsize = maxsize;
        top=-1;
    
    public E push(E e) 
        if(!isFull())
            arr[++top] = e;
            return e;
        
        return null;
    

    public E pop() 
        if(!isEmpty())
            return (E) arr[top--];
        
        return null;
    

    public E peek() 
         if(!isEmpty())
             return (E) arr[top];
         
         return null;
    

    public boolean isEmpty() 
        if(top == -1)
            return true;
        
        else return false;
    

    public int size() 
        if(!isEmpty())
            return top+1;
        
       return 0;
    

    public void clear() 
        if (!isEmpty())
            top=-1;
        

    
    public boolean isFull()
        if (top == maxsize)
            return true;
        
        else return false;
    

4.测试顺序栈

public class TestSeqStack 
    public static void main(String []args)
        Integer data[] =1,24,32,3,33;
        SeqStack<Integer> seqStack = new SeqStack<Integer>(5);

        System.out.println("*******************");
        for(int i= 0;i<5;i++)
            System.out.print("入栈:"+data[i]);
            seqStack.push(data[i]);
            System.out.println();
        
        System.out.println("*******************");
        while(true)
            if(seqStack.isEmpty())
                break;
            
            System.out.print("出栈:"+seqStack.pop().intValue());

            System.out.println();
        
    

五.用链栈实现栈

1.链栈的存储结构
链式存储结构存储的栈称为链栈(linked stack)。链栈通常用单链表来表示。
链栈结点的结构与单链表结点的结构一样,由数据域data和引用域next两部分组成。
栈顶指示器指向最后一个入链的元素。
2.单链节点

public class StackNode<E> 
    private E data;
    private StackNode<E> next; //指向下一个节点

    public StackNode()
    public StackNode(E data) 
        this.data = data;
    

    public StackNode(E e, StackNode<E> e1)
        this.data = e;
        this.next = e1;

    

    public E getData() 
        return data;
    

    public void setData(E data) 
        this.data = data;
    

    public StackNode<E> getNext() 
        return next;
    

    public void setNext(StackNode<E> next) 
        this.next = next;
    

3.单链节点实现链栈

public class LinkStack<E> implements IStack<E> 
    private StackNode<E> top;
    private int size;

    public LinkStack()
        top = new StackNode<E>(null,null);
        size=0;
    
    public E push(E e) 
        StackNode<E> node = new StackNode<E>(e,top.getNext());
        top.setNext(node);
        size++;
        return e;
    

    public E pop() 
        if(top.getNext() !=null)
            E e = top.getNext().getData();
            top.setNext(top.getNext().getNext());
            size--;
            return e;
        
        return null;
    

    public E peek() 
        if(top.getNext()!=null)
            return top.getNext().getData();
        
        return null;
    

    public boolean isEmpty() 
        if(top.getNext()!=null)
            return false;
        
        return true;
    

    public int size() 
        return size;
    

    public void clear() 
        top.setNext(null);
    

4.测试

public class TestLinkStack 
    public static void main(String []args)
        Integer data[] =1,24,32,3,33;
        LinkStack<Integer> linkStack = new LinkStack<Integer>();

        System.out.println("*******************");
        for(int i= 0;i<5;i++)
            System.out.print("入栈:"+data[i]);
            linkStack.push(data[i]);
            System.out.println();
        
        System.out.println("*******************");
        while(true)
            if(linkStack.isEmpty())
                break;
            
            System.out.print("出栈:"+linkStack.pop().intValue());

            System.out.println();
        
    


六.总结

到了这里,栈的知识大概就差不多了解了。
如果有什么问题,欢迎大家评论指出,3q!

附上视频教学连接:
中国MOOC数据结构

以上是关于详解数据结构中栈的定义和操作的主要内容,如果未能解决你的问题,请参考以下文章

python中栈的实现

Java中栈的两种实现

Java中栈的使用

数据结构 栈的简单理解和基本操作

单片机中栈和堆的区别是啥?

Java中栈的创建与其常见的应用场景