【数据结构】栈和队列(栈的基本操作和基础知识)

简介: 【数据结构】栈和队列(栈的基本操作和基础知识)

栈的概念和结构

image.png

栈的实现

栈有数组栈和链式栈。数据结构没有规定栈的实现要用数组还是链式,根据自身需要选择即可。

在数组栈中,左边是栈底,右边是栈顶。因为数组尾插尾删方便,也符合栈顶元素先出。

在用单链表实现时,栈顶只能是左边。因为单链表的头插头删方便。

image.png

数组栈的实现

总的声明

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<stdbool.h>


typedef int STDataType;

typedef struct Stack
{
   
   
    int* a;
    int top;   //标识栈的位置
    int capacity;
}ST;

void STInit(ST* pst);
void STDestroy(ST* pst);

//栈顶插入删除
void STPush(ST* pst, STDataType x);
void STPop(ST* pst);
STDataType STTop(ST* pst);

bool STEmpty(ST* pst);
int STSize(ST* pst);

初始化


void STInit(ST* pst)
{
   
   
    assert(pst);

    pst->a = NULL;
    pst->capacity = 0;
    pst->top = 0;
    //pst->top = -1;
}

上方代码中,pst->top可以初始化为0,也可以为-1。不过两种方法需要区分:

第一种
image.png
top指向栈顶元素,当top初始化为0时,会产生歧义,即当有一个数据或者为空时,top都等于0。

下面是解决方法:
image.png
分析:当它为空时,top==0。当有一个数据时,top==1,即top是指向栈顶元素的下一个位置。

如果我们想用这种方式实现数组栈,尾插时,就直接把x赋给top位置,然后再让top指向下一位置。

第二种:
image.png
分析:我们初始化top为-1,此时为空。当有一个数据时,top==0,刚好指向栈顶元素。尾插时,需要先让top指向下一位置,再插入元素。

两种方法都可以使用,这里我们使用初始化top为0的方法。 注意:使用不同的方法,其他操作的实现会略微不同。

插入


void STPush(ST* pst, STDataType x)
{
   
   
    assert(pst);
    if (pst->top == pst->capacity)
    {
   
   
        int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2;
        STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * newcapacity);
        if (tmp == NULL)
        {
   
   
            perror("realloc fail");
            return;
        }
        pst->a = tmp;
        pst->capacity = newcapacity;
    }
    pst->a[pst->top] = x;
    pst->top++;
}

删除


void STPop(ST* pst)
{
   
   
    assert(pst);
    assert(pst->top > 0);
    pst->top--;
}

取栈顶元素


STDataType STTop(ST* pst)
{
   
   
    assert(pst);
    assert(pst->top > 0);
    return    pst->a[pst->top - 1];
}

销毁



void STDestroy(ST* pst)
{
   
   
    free(pst->a);
    pst->a = NULL;
    pst->capacity = pst->top = 0;

}

判断是否为空


bool STEmpty(ST* pst)
{
   
   
    assert(pst);
    //if (pst->top == 0)
    //{
   
   
    //    return true;
    //}
    //else
    //{
   
   
    //    return    false;
    //}
    return pst->top == 0;
}

返回栈的大小


int STSize(ST* pst)
{
   
   
    assert(pst);
    return pst->top;
}

栈的一对多关系

image.png
如上图,我们的入栈顺序是123456,出栈顺序是346521。可知入栈顺序和出栈顺序是一对多的关系。入栈顺序只有一种,但出栈的顺序是多样的,不过出栈顺序也要符合先出栈顶元素,不是想出啥就出啥 。

不同的栈

image.png
栈有两种,一种是数据结构的栈,一种是内存区域的栈。我们这里的栈是数据结构的栈。而我们所说的栈溢出是指内存区域的栈,在递归中,返回条件出现问题时,容易出现栈溢出。

目录
相关文章
|
7天前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
71 9
|
1天前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
|
4天前
|
存储 JavaScript 前端开发
执行上下文和执行栈
执行上下文是JavaScript运行代码时的环境,每个执行上下文都有自己的变量对象、作用域链和this值。执行栈用于管理函数调用,每当调用一个函数,就会在栈中添加一个新的执行上下文。
|
6天前
|
存储
系统调用处理程序在内核栈中保存了哪些上下文信息?
【10月更文挑战第29天】系统调用处理程序在内核栈中保存的这些上下文信息对于保证系统调用的正确执行和用户程序的正常恢复至关重要。通过准确地保存和恢复这些信息,操作系统能够实现用户模式和内核模式之间的无缝切换,为用户程序提供稳定、可靠的系统服务。
27 4
|
10天前
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
23天前
数据结构(栈与列队)
数据结构(栈与列队)
16 1
|
28天前
|
存储 JavaScript 前端开发
为什么基础数据类型存放在栈中,而引用数据类型存放在堆中?
为什么基础数据类型存放在栈中,而引用数据类型存放在堆中?
63 1
|
24天前
【数据结构】-- 栈和队列
【数据结构】-- 栈和队列
13 0
|
29天前
探索数据结构:队列的的实现与应用
探索数据结构:队列的的实现与应用
|
29天前
|
算法 程序员 索引
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器
栈的基本概念、应用场景以及如何使用数组和单链表模拟栈,并展示了如何利用栈和中缀表达式实现一个综合计算器。
26 1
数据结构与算法学习七:栈、数组模拟栈、单链表模拟栈、栈应用实例 实现 综合计算器

热门文章

最新文章