数据结构学习:栈

news2024/12/23 18:14:42

栈的简介

栈(Stack)是限定仅在表尾进行插入租删除操作的线性表。

允许插入和删除的一端称为栈顶(top),另-端称为栈底(bottom)

不含任何数据元素的栈称为空栈

栈又称为后进先出的线性表,简称LIFO结构

栈的插入操作,也叫做进栈,压栈,入栈

栈的删除操作,叫做出栈

以下是栈的示意图,

栈的C语言编写

因为栈也是线性表的一种,所以也包括两种类型,顺序栈和链式栈。

顺序栈

单链表在C语言下编写的结构代码如下,

#define MAXSIZE 128 
typedef int data_t;

/* 1 */
/*typedef struct 
{
    data_t data[MAXSIZE];
    int last;

}Sqstack,*Sqstacklist;*/

/*下面编写另一种形式的栈结构建立*/
/*这种建立方式会让后面的编程相较顺序表的编程来说变难
但是用户可以自主设定data中的数据容量*/
typedef struct 
{
    data_t *data;/*将数据由原来的数组转变设置为一个指向数据地址的指针*/
    int maxlen;/*多加入一个参数,用于设定数据的最大长度,主要体现在malloc申请内存时*/
    int top;/*指示栈顶的位置的变量,指定的是数组下标*/

}Sqstack;

下面我们将编写一些顺序表相关的函数,在编写时我们一般会创建三个文件,分别是sqlist.h,sqlist.c,test.c,其中sqlist.h用于编写一些数据结构的定义和函数结构,sqlist.c用于编写函数具体实现,test.c用于测试每个函数是否正确。

在sqlist.h文件中,编写的程序如下,

#define MAXSIZE 128 
typedef int data_t;

/* 1 */
/*typedef struct 
{
    data_t data[MAXSIZE];
    int last;

}Sqstack,*Sqstacklist;*/

/*下面编写另一种形式的栈结构建立*/
/*这种建立方式会让后面的编程相较顺序表的编程来说变难
但是用户可以自主设定data中的数据容量*/
typedef struct 
{
    data_t *data;/*将数据由原来的数组转变设置为一个指向数据地址的指针*/
    int maxlen;/*多加入一个参数,用于设定数据的最大长度,主要体现在malloc申请内存时*/
    int top;/*指示栈顶的位置的变量,指定的是数组下标*/

}sqstack;

sqstack * stack_creat(int len);
int stack_push(sqstack *s,data_t value);
int stack_empty(sqstack *s);
int stack_full(sqstack *s);
data_t stack_pop(sqstack *s);
data_t stack_top(sqstack *s);
int stack_clear(sqstack *s);
int stack_free(sqstack *s);


在sqlist.h文件中,我们编写相关函数的具体实现,以下是每个操作API函数的实现,

创建顺序栈

/*创建栈,len表示数据的长度*/
sqstack * stack_creat(int len)
{
    sqstack *s;
    /*申请内存*/
    /*先为结构体申请内存*/
    if((s = (sqstack*)malloc(sizeof(sqstack))) == NULL)
    {
        printf("malloc sqstack fail\n");
        return NULL;
    }

    /*由于现在的数据是用指针存储,而上面申请时只是申请了结构体内三个元素的内存,所以我们还需要申请数据的内存*/
    if((s->data = (data_t*)malloc(sizeof(data_t)*len)) == NULL)
    {
        printf("malloc data fail\n");
        free(s->data);
        return NULL;
    }

    /*赋初值*/
    /*从s->data开始,每个部分都放0,放的长度len*sizeof(data_t),也就是把数据的初值都赋为0*/
    memset(s->data,0,len*sizeof(data_t));

    s->maxlen = len;
    s->top = -1;
    return s;

}

入栈

/*入栈函数*/
int stack_push(sqstack *s,data_t value)
{
    if(s == NULL)
    {
        printf("stack is null\n");
        return -1;
    }
    /*判断是否为满*/
    if(s->top == s->maxlen-1)
    {
        printf("stack is full\n");
        return -1;
    }

    s->top = s->top+1
    s->data[s->top] = value;
    return 0;
}

出栈 

/*出栈*/
data_t stack_pop(sqstack *s)
{
    data_t data;
    if(s == NULL)
    {
        printf("stack is null\n");
        return -1;
    }
    /*判断栈中是否有值,没有值无法进行*/
    if(s->top == -1)
    {
        printf("stack is empty");
        return 0;
    }

    data = s->data[s->top];
    s->top--;
    return s;
}

释放栈空间

/*释放栈空间*/
int stack_free(sqstack *s)
{
    /*由于我们malloc申请了两个部分的空间,所以都要释放*/
    /*并且我们得先释放结构体中的data_t* 的内存,在释放stack的内存*/
    if(s->data != NULL)
        free(s->data);

    free(s);
}

简单查看函数

 

/*判断是否是空栈*/
int stack_empty(sqstack *s);
{
    if(s == NULL)
    {
        printf("stack is null\n");
        return -1;
    }
    /*三目运算表示,top等于-1返回1表示是空,否则返回0*/
    return(s->top == -1?1:0);

}

/*判断是否满栈*/
int stack_full(sqstack *s)
{
    if(s == NULL)
    {
        printf("stack is null\n");
        return -1;
    }  

    return(s->top == len-1?1:0);  
}


/*查看栈顶元素*/
data_t stack_top(sqstack *s)
{
    return s->data[s->top];
}

/*清除栈元素*/
int stack_clear(sqstack *s)
{
    if(s == NULL)
    {
        printf("stack is null\n");
        return -1;
    }

    /*由于清理元素不是释放内存,所以我们只需要调整top即可告诉用户链表无值*/
    s->top = -1;
    return 0;

}

链式栈

链式栈其实就是给单链表加一个限制,就是链表的插入和删除操作只允许在链表的头部进行,链表尾部就是栈底,头指针就是栈顶指针。

同样,链式栈我们依旧编写其相关函数进行学习,如下,

typedef int data_t;

typedef struct node
{
    data_t data;
    struct node* next;

    
}linknode,*linkstack;

linkstack stack_create();
int stack_push(linkstack s,data_t value);
data_t stack_pop(linkstack s);
int stack_empty(linkstack s);
int stack_top(linkstack s);
linkstack stack_free(linkstack);

创建链式栈

linkstack stack_create()
{
    linkstack s;
    s = (linkstack)malloc(sizeof(linknode)); 

    if(s == NULL)
    {
        printf("malloc linkstack fail");
        return NULL;
    }

    s->data = 0;
    s->next = NULL;
    return s;

}

 入栈

/*入栈*/
int stack_push(linkstack s,data_t value)
{
    linkstack p;
    if(s == NULL)
    {
        printf("linkstack is null");
        return -1;
    }

    p = (linkstack)malloc(sizeof(linknode));
    if(p == NULL)
    {
        printf("malloc fail\n");
        return -1;
    }

    /*先赋初值(习惯)*/
    p->data = value;
    p->next = NULL

    p->next = s->next;

    s->next = p;

    return 0;
}

出栈

/*出栈*/
data_t stack_pop(linkstack s)
{
    data_t data;
    linkstack p;
    if(s == NULL)
    {
        printf("linkstack is null");
        return 0;
    }

    data = s->next->data;
    p = s->next;
    s->next = p;

/*删除就是把这个部分释放掉,且要将指针赋NULL,防止野指针*/
    free(p);
    p = NULL;

    return data;
}

释放栈空间

/*释放栈的空间*/
linkstack stack_free(linkstack s)
{
    linkstack p;
    if(s == NULL)
    {
        printf("linkstack is null");
        return NULL;
    }

    while(s != NULL)
    {
        p = s;
        s = p->next;
        free(s);

    }

    return NULL;

}

简单查看函数

/*判断栈是否为空栈*/
int stack_empty(linkstack s)
{
    if(s == NULL)
    {
        printf("linkstack is null");
        return -1;
    }    

    return(s->next == NULL?1;0);
}

/*查看栈顶元素*/
data_t stack_top(linkstack s)
{
    if(s == NULL)
    {
        printf("linkstack is null");
        return -1;
    } 

    return(s->next->data); 
}

针对数据结构与算法的学习主要是从代码编程的角度进行学习,建议大家学习完相关理论知识后,还是自己进行敲一下代码,这样对数据结构的学习更有帮助!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2079619.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java JVM

JVM的组成 Java虚拟机(JVM)是执行Java字节码的运行时环境。它由以下几个主要部分组成: 1. **类加载器(ClassLoader)**: - 负责加载Java类的字节码到JVM中,并进行链接和初始化。 关于Java的…

C++基础练习

1》提示并输入一个字符串&#xff0c;统计该字符串中字母个数、数字个数、空格个数、其他字符的个数 1 #include<iostream>2 using namespace std;3 4 int main()5 {6 string str1; //定义字符串数据7 cout << "请输入一个字符串>>>" ;8…

三种常用的Word打印部分内容操作技巧

作为打工人&#xff0c;我们经常需要处理Word文档&#xff0c;有时还会遇到只需要打印文档中的部分内容而非整个文档的情况。为了高效地完成这一任务&#xff0c;Word提供了多种灵活的设置方法。本文将详细介绍三种常用的方法来帮助你实现只打印Word文档中的部分内容。 方法一&…

第一周学习--联邦学习

OUC读研--第一周 目录 1、课程学习 2、fedavg的算法实现 关于代码详解 1、client __init__ 方法 local_train 方法 2、server 3、get_dataset 函数定义 数据集加载 MNIST 数据集 CIFAR-10 数据集 返回值 使用示例 4、 main 代码解释 可能的改进点 5、models …

机器学习之 K-means算法的代码实现

K-means 算法简介 K-means 是一种常用的无监督学习算法&#xff0c;主要用于数据聚类。它的主要思想是将数据集中的数据分成 K 个簇&#xff08;Cluster&#xff09;&#xff0c;使得簇内的数据点尽可能相似&#xff0c;而簇间的差异尽可能大。K-means 算法的核心步骤包括初始…

关于类与构造函数继承的小挑战

题目 /* 使用构造函数将电动汽车&#xff08;称为 EV&#xff09;作为 Car 的子 “类 ”来实现。除了品牌和当前速度外&#xff0c;EV 还具有当前电池电量&#xff08;百分比&#xff09;&#xff08;“charge ”属性&#xff09;&#xff1b;实现一个 “chargeBattery ”方法…

Vitis AI 基本认知(Tiny-VGG 项目代码详解)

目录 1. 简介 1.1 Tiny-VGG 1.2 data 目录结构 2. 代码分析 2.1 Import packages 2.2 Dataset 2.3 Train step 2.4 Vali & Test step 2.5 Ceate model 2.6 Compile model 2.6.1 计算 loss 2.6.2 计算平均值 3.6.3 计算准确度 2.7 训练循环 2.7.1 自定义训练…

BLE蓝牙协议详解

BLE蓝牙协议详解 1、BLE协议栈 1、协议栈结构 蓝牙LE协议栈按功能分为三个层&#xff1a;Controller、Host和Application Profiles and Services。 HCI event是按BLE Spec标准设计的&#xff0c;是BLE Controller和Host用来交互的事件&#xff1b;GAP event是BLE host定义的…

环境配置 --- miniconda安装torch报错OSError: [WinError 126] 找不到指定的模块

环境配置 — miniconda安装torch报错OSError: [WinError 126] 找不到指定的模块。 CSDN 原因&#xff1a;fbegmm.dll文件出现问题 解决方案&#xff1a; 使用依赖分析工具https://github.com/lucasg/Dependencies/releases/tag/v1.11.1 检测报错提示的那个dll文件发现哪个文…

Nuclei:开源漏洞扫描器

Nuclei 拥有灵活的模板系统&#xff0c;可以适应各种安全检查。 它可以使用可自定义的模板向多个目标发送请求&#xff0c;确保零误报并实现跨多台主机的快速扫描。 它支持多种协议&#xff0c;包括 TCP、DNS、HTTP、SSL、文件、Whois、Websocket 等。 特征 模板库&#xf…

Java中的定时器(Timer)

目录 一、什么是定时器? 二、标准库中的定时器 三、实现定时器 一、什么是定时器? 定时器就像一个"闹钟"&#xff0c;当它到达设定的时间后&#xff0c;就会执行预定的代码。 例如&#xff0c;我们在TCP的超时重传机制中讲过&#xff0c;如果服务器在规定的时间…

XDMA - AXI4 Memory Mapped

目录 1. What is SG DMA2. Descriptor3. Transfer for H2CStep 1. The host prepares stored data and creates descriptors in main memoryStep 2. The host enables DMA interruptsStep 2. The driver initializes DMA with descriptor start addressStep 3. The driver writ…

数据结构(邓俊辉)学习笔记】串 06——KMP算法:构造next[]表

文章目录 1. 递推2. 算法3. 实现 1. 递推 接下来的这节&#xff0c;我们就来讨论 next 查询表的构造算法。我们将会看到非常有意思是&#xff0c; next 表的构造过程与 KMP 主算法的流程在本质上是完全一样的。 在这里&#xff0c;我们不妨采用递推策略。我们只需回答这样一个…

带你深入浅出新面经:十六、十大排序之快速排序

此为面经第十六谈&#xff01;关注我&#xff0c;每日带你深入浅出一个新面经。 我们要了解面经要如何“说”&#xff01; 很重要&#xff01;很重要&#xff01;很重要&#xff01; 我们通常采取总-分-总方式来阐述&#xff01;&#xff08;有些知识点&#xff0c;你可以去…

python脚本请求数量达到上限,http请求重试问题例子解析

在使用Python的requests库进行HTTP请求时&#xff0c;可能会遇到请求数量达到上限&#xff0c;导致Max retries exceeded with URL的错误。这通常发生在网络连接不稳定、服务器限制请求次数、或请求参数设置错误的情况下。以下是一些解决该问题的策略&#xff1a; 增加重试次数…

【负载均衡式在线OJ】项目设计

文章目录 程序源码用到的技术项目宏观结构代码编写思路 程序源码 https://gitee.com/not-a-stupid-child/online-judge 用到的技术 C STL 标准库。Boost 准标准库(字符串切割)。cpp-httplib 第三方开源网络库。ctemplate 第三方开源前端网页渲染库。jsoncpp 第三方开源序列化…

栈和队列有何区别?

栈和队列是两种常见的数据结构&#xff0c;它们分别用于解决不同类型的问题。在程序设计中&#xff0c;栈和队列都是非常重要的数据结构&#xff0c;因为它们可以帮助我们解决很多实际的问题。 栈&#xff1a; 首先&#xff0c;让我们来讨论栈, 栈是一种后进先出&#xff08;…

学NLP不看这本书等于白学!一书弄懂NLP自然语言处理(附文档)

随着人工智能技术的飞速发展&#xff0c;自然语言处理成为了计算机科学与人工智能领域中不可或缺的关键技术之一。作为一名长期致力于人工智能和自然语言处理研究的学者&#xff0c;今天给大家推荐的这本《自然语言处理&#xff1a;大模型理论与实践》正是学NLP自然语言非常牛逼…

黑神话悟空用什么编程语言

《黑神话&#xff1a;悟空》作为一款备受瞩目的国产单机动作游戏&#xff0c;其背后的开发涉及了多种编程语言和技术。根据公开信息和游戏开发行业的普遍做法&#xff0c;可以推测该游戏主要使用了以下几种编程语言&#xff1a; C&#xff1a; 核心编程语言&#xff1a;作为《黑…

【C++ Primer Plus习题】5.7

问题: 解答: #include <iostream> #include <string> using namespace std;typedef struct _Car {string brand;int year; }Car;int main() {int count 0;cout << "请问你家有多少辆车呢?" << endl;cin >> count;cin.get();Car* ca…