首页 > 其他分享 >[数据结构] 栈

[数据结构] 栈

时间:2024-02-06 12:22:40浏览次数:33  
标签:int top 元素 栈顶 数据结构 Stack 指针

栈的定义及特点

栈(Stack)是只允许在一端进行插入或删除操作的线性表,如图所示:

image

栈顶(top):线性表允许进行插入、删除的一端;

栈底(bottom):不允许进行插入和删除的一端;

空栈:不含任何元素的空表。

如上图所示,设某个栈\(S=(a_1, a_2, a_3, a_4, a_5)\),则\(a_1\)为栈底元素,\(a_5\)为栈顶元素。进栈顺序为\(a_1, a_2, a_3, a_4, a_5\),出栈顺序为\(a_5, a_4, a_3, a_2, a_1\),由此可见,栈的操作特性可以明显地概括为先进后出、后进先出

栈的顺序存储

采用顺序存储的栈称为顺序栈,它利用一组地址连续的存储单元存放自栈底到栈顶的数据元素,同时设置一个指针top指示当前栈顶元素的位置

  • 结构体

    #define MaxSize 50
    typedef struct {
        int data[MaxSize];
        int top;
    }Stack;
    

    栈顶指针 :S.top,初始设置为-1;栈顶元素:S->data[S.top]

    进栈操作:栈不满时,栈顶指针++,再送值到栈顶;

    出栈操作:栈非空时,取栈顶元素,栈顶指针--

    栈空条件:S.top=-1,栈满条件:S.top==MaxSize - 1,栈长:S.top+1

    bool StackEmpty(Stack *S) {
        if(S->top == -1)
            return true;
        else
            return false;
    }
    
  • 入栈

    首先咱要初始化栈

    void InitStack(Stack *s) {
        S->top == -1;
    }
    

    然后咱看图

    这是初始化的情况

image

元素\(a_1\)入栈

image

元素\(a_2\)入栈

image

以此类推

给出代码:

void Push(Stack *S, int x) {
    if(S->top == MaxSize - 1)
        return ; // 栈满
    S->top ++;
    S->data[S->top] = x;
}
  • 出栈

    元素\(a_2\)出栈

image

元素\(a_1\)出栈

image

代码:

void Pop(Stack *S, int *x) {
    if(S->top == -1)
        return ; // 栈空
    *x = s->data[S->top --];
}

共享栈

利用栈底位置相对不变的特性,让两个顺序栈共享一个一维数组空间,将两个栈的栈底分别设置在共享空间的两端,栈顶分别向共享空间的中间延伸,如下图所示:

image

两个栈的栈顶指针都指向栈顶元素,top0 = -1时0号栈为空,top1 = MaxSize - 1时1号栈为空;当且仅当两个栈顶指针相邻(top1 - top0 = 1)时栈满。

共享栈是为了更好有效地利用存储空间,两个栈的空间相互调节,只有在整个存储空间被占满时才会发生上溢。其存取数据的时间复杂度均为O(1)

链栈

采用链式存储的栈称为链栈,链栈的优点是便于多个栈共享存储空间和提高效率,且不存在栈满上溢的情况。通常采用单链表实现,并且规定所有的操作都是在单链表表头进行。这里规定链栈没有头节点。

下面给出一些基本操作的代码:

  • 初始化

    typedef struct StackNode {
        int data; // 数据域
        struct StackNode *next; // 指向下一个节点的指针
    } StackNode;
    
    typedef struct Stack {
        StackNode *top; // 栈顶指针
    } Stack;
    
    void init_stack(Stack *S) {
        S->top = NULL; // 初始化栈顶指针为空,表示栈为空
    }
    
  • 判空

    int is_empty(Stack *S) {
        return S->top == NULL; // 如果栈顶指针为空,表示栈为空,返回 1,否则返回 0
    }
    
  • 进栈

    void push(Stack *S, int x) {
        StackNode *new_node = (StackNode*)malloc(sizeof(StackNode)); // 创建新结点
        new_node->data = x; // 将数据存入新结点的数据域
        new_node->next = S->top; // 将新结点插入到栈顶之后
        S->top = new_node; // 更新栈顶指针
    }
    
  • 出栈

    int pop(Stack *S) {
        if (S->top == NULL) { // 如果栈为空,则输出错误信息并返回
            printf("栈为空\n");
            return -1;
        }
        int x = S->top->data; // 取出栈顶元素
        StackNode *temp = S->top; // 保存栈顶指针
        S->top = S->top->next; // 栈顶指针指向下一个节点
        free(temp); // 释放原栈顶节点的内存
        return x; // 返回栈顶元素
    }
    

写在最后

后续应该还会补充一个完整的代码,敬请等待。

标签:int,top,元素,栈顶,数据结构,Stack,指针
From: https://www.cnblogs.com/wanyy-home/p/18009522

相关文章

  • 经典数据结构题目-图
    图200.岛屿数量思路遍历二维数组,遇到等于1的进行计算。同时修改同岛的位置为0,避免重复计算遍历同岛的位置,可以采用dfs深度优先搜索代码char[][]g;publicintnumIslands(char[][]grid){intsum=0;g=grid;for(inti=0;......
  • 有关各种数据结构模板
    FHQ-Treap模板题-普通平衡树#include<bits/stdc++.h>#definelstr[u].l#definerstr[u].rusingnamespacestd;constintN=3e5+10;structNode{intl,r;intkey,v;intsize;}tr[N];introot,idx;intn,m;voidpushup(intu){tr[u].size......
  • 2.1 不会有人数据结构比我还菜吧?
    记录三道自己菜死了的与根号有关的题。其中每道题都有polylog解法。题目名称太长了,就不放了。CF1017GTheTree根号做法:考虑操作分块,然后建虚树。建出虚树之后我们就发现很好处理了。同样的,处理每一个块结束后的真实形态,也可以借助这个虚树。总的来说,需要暴力维护一下每个虚......
  • 数据结构(一)单链表---以题为例
    实现一个单链表,链表初始为空,支持三种操作:向链表头插入一个数;删除第 k 个插入的数后面的数;在第 k 个插入的数后插入一个数。现在要对该链表进行 M 次操作,进行完所有操作后,从头到尾输出整个链表。注意:题目中第 k 个插入的数并不是指当前链表的第 k 个数。例如操作......
  • 数据结构之——数组
    数组数据结构的基本类型之一,它可以构成其他数据结构,如栈、队列、哈希表、树、图、堆、矩阵、张量。数组在内存中的存储方式为一片连续的内存空间,其基本操作与其他数据结构一致,即所谓的增删改查。废话不多说,上代码加以理解。Java类型实现classarray{publicstaticvoid......
  • redis有5种数据结构
    redis有5种数据结构,分别如下:5种数据结构python语言对5种数据结构的增删改查全局函数1|0redis连接importredispool=redis.ConnectionPool(host='localhost',port=6379,decode_responses=True)r=redis.Redis(connection_pool=pool)redis取出的结果默认是字节,可......
  • Python数据结构与算法06——树与树算法
    二叉树classNode(object):def__init__(self,val,lchild=None,rchild=None):self.val=valself.lchild=lchildself.rchild=rchildclassTree(object):def__init__(self):self.root=Nonedefadd(self,item):no......
  • [数据结构] 链表
    写在前面菜鸡博主开始复习了,先从数据结构开始吧(其实是每天复习高数太累了)1.单链表单链表是线性表的链式存储,是指通过一组任意的存储单元来存储线性表中的数据元素。对每个链表节点,除了存放元素自身的信息之外,还需要存放一个指向其后继的指针(如下图所示)单链表的节点可以用如......
  • 20240201-高级数据结构随记
    intmain(){intn;cin>>n;for(inti=1;i<=n;i++){scanf("%d",&a[i]);sum[i]=sum[i-1]+a[i];}intmn=sum[0];for(inti=1;i<=n;i++){//枚举右端点if(sum[i]-mn>ans)ans=sum[i]-mn;......
  • 20240201-高级数据结构总结
    待办:倍增并查集线段树合并set逆序对树动态开点线段树套用模版#include<bits/stdc++.h>usingnamespacestd;#defineM100005#definelllonglongstructnode{ intL,R,cnt,vis;}tree[400005];inta[M],b[M],c[M],f[M];voidbuild(intp,intl,intr){ tre......