栈的链式存储(详解)

栈的链式存储

栈的链式存储是通过链表来实现的,每个节点包含一个元素和一个指向下一个节点的指针。链式存储的栈不需要提前分配内存空间,可以动态地增加或减少元素。

在链式存储中,栈顶元素通常是链表的头节点,栈底元素是链表的末尾节点。通过链表的插入和删除操作,可以轻松实现栈的基本操作:

  1. 入栈操作(push):创建一个新节点,将新元素放入节点中,然后将新节点插入链表的头部,成为新的栈顶节点。
  2. 出栈操作(pop):将链表头部的节点取出,并将头指针指向下一个节点,成为新的栈顶节点。
  3. 栈空判断:当链表为空时,表示栈为空。
  4. 栈满判断:链式存储的栈一般不会满,除非内存耗尽。

链式存储的栈操作灵活,但由于每个节点需要额外的指针空间,可能会占用更多的内存。另外,由于链式存储的特性,访问栈中特定位置的元素可能需要遍历整个链表,导致性能略低于顺序存储。

线性表的链式存储:受到限制的线性表

在这里插入图片描述栈的链式存储项目结构
在这里插入图片描述
链式存储的头文件LinkedStorage.h
在这里插入图片描述头文件LinkedStorage.h代码

#ifndef LINKSTACK_H
#define LINKSTACK_H
#include <stdio.h>
#include <stdlib.h>
// 链式栈的节点
typedef struct LINKNODE {
	struct LINKNODE* next;
}LinkNode;
// 链式栈
typedef struct LINKSTACK {
	LinkNode head;
	int size;

}LinkStack;


// 初始化函数
LinkStack* Init_LinkStack();
// 入栈
void Push_LinkStack(LinkStack* stack, LinkNode* data);
// 出栈
void Pop_LinkStack(LinkStack* stack);
// 返回栈顶元素
LinkNode* TopLinkStack(LinkStack* stack);
// 返回栈元素的个数
int Size_LinkStack(LinkStack* stack);
// 清空栈
void Clear_LinkStack(LinkStack* stack);
// 销毁栈
void FreeSpace_LinkStack(LinkStack* stack);
#endif

c语言文件代码LinkedStorage.cpp
在这里插入图片描述cpp代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <string.h>
#include "LinkedStorage.h"

// 初始化函数
LinkStack* Init_LinkStack() {
         LinkStack* stack = (LinkStack*)malloc(sizeof(LinkStack));
         stack->head.next = NULL;
         stack->size = 0;
         return stack;
};
// 入栈
void Push_LinkStack(LinkStack* stack, LinkNode* data) {
    if (stack == NULL) {
        return;
    }
    if (data == NULL) {
        return;
    }
    // 入栈
    data->next = stack->head.next;
    stack->head.next = data;
    stack->size++;
};
// 出栈
void Pop_LinkStack(LinkStack* stack) {
    if (stack == NULL) {
        return;
    }
    if (stack->size == 0) {
        return;
    }

    // 第一个有效节点
    LinkNode* pNext = stack->head.next;
    stack->head.next = pNext->next;
    stack->size--;



};
// 返回栈顶元素
LinkNode* TopLinkStack(LinkStack* stack) {
    if (stack == NULL) {
        return NULL;
    }
    if (stack->size == 0) {
        return NULL;
    }
    // 返回栈顶元素
    return stack->head.next;
};

// 返回栈元素的个数
int Size_LinkStack(LinkStack* stack) {
    if (stack == NULL) {
        return -1;
    }
    return stack->size;
};
// 清空栈
void Clear_LinkStack(LinkStack* stack) {
    if (stack == NULL) {
        return;
    }
    // 清空栈
    stack->head.next = NULL;
    stack->size = 0;

};
// 销毁栈
void FreeSpace_LinkStack(LinkStack* stack) {
    if (stack == NULL) {
        return;
    }
    free(stack);
};

项目主文件代码
在这里插入图片描述main主文件代码

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <string.h>
#include "LinkedStorage.h"

typedef struct PERSON {
	LinkNode node;
	char name[64];
	int age;
}Person;


int main(void) {
    // 创建栈
	LinkStack* stack = Init_LinkStack();
    // 创建数据
	Person p1, p2, p3, p4, p5;
	// 将数据传递进入数组
	strcpy(p1.name, "fff");
	strcpy(p2.name, "qqq");
	strcpy(p3.name, "hhh");
	strcpy(p4.name, "ooo");
	strcpy(p4.name, "yyy");
    // 创建年龄类型的数据
	p1.age = 22;
	p2.age = 23;
	p3.age = 24;
	p4.age = 25;
	p5.age = 26;
	//入栈
	Push_LinkStack(stack, (LinkNode*)&p1);
	Push_LinkStack(stack, (LinkNode*)&p2);
	Push_LinkStack(stack, (LinkNode*)&p3);
	Push_LinkStack(stack, (LinkNode*)&p4);
	Push_LinkStack(stack, (LinkNode*)&p5);
	// 输出
	while (Size_LinkStack(stack) > 0) {
	    // 取出栈顶元素
		Person* p = (Person*)TopLinkStack(stack);
		printf("Name = %s Age = %d\n", p->name, p->age);
		// 弹出栈顶元素
		Pop_LinkStack(stack);
	}
	// 销毁栈
	FreeSpace_LinkStack(stack);

	system("pause");
	return 0;

}

项目运行结果展示
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

识KDJ指标,看懂超买超卖信号

一、认识KDJ 1、KDJ的含义 KDJ分析股票中短期趋势的一个常用指标&#xff0c;中文名称“随机指标”。它是一个综合考虑股票最高价、最低价和收盘价的技术指标&#xff0c;能够帮助我们根据历史价格预测出股票未来的价格走势。在实际应用的过程中&#xff0c;它的短期预测功能要…

AArch64中的虚拟化

运行在EL2或更高级别的软件具有对虚拟化的几个控制权限&#xff1a; • 第二阶段翻译&#xff08;Stage 2 translation&#xff09; • EL1/0指令和寄存器访问trapping • 虚拟异常生成 非安全状态和安全状态下的异常级别&#xff08;ELs&#xff09;如下图所示&#xff1a; 在…

使用Java语言实现变量互换

一、 java运算 通过异或运算符实现两个变量的互换 import java.util.Scanner;public class ExchangeValueDemo {public static void main(String[] args){try (Scanner scan new Scanner(System.in)) {System.out.println("请输入A的值&#xff1a;");long A sca…

Android实验:绑定service实验

目录 实验目的实验内容实验要求项目结构代码实现代码解释结果展示 实验目的 充分理解Service的作用&#xff0c;与Activity之间的区别&#xff0c;掌握Service的生命周期以及对应函数&#xff0c;了解Service的主线程性质&#xff1b;掌握主线程的界面刷新的设计原则&#xff…

Linux 编译安装colmap

COLMAP可以作为独立的app&#xff0c;通过命令行或者图形交互界面使用&#xff0c;也可以作为一个库被包含到其他源代码中。 这里记录一下编译安装colmap的过程&#xff0c;首先需要安装好CUDA&#xff0c;CUDA具体安装过程这里就不赘述了。在GitHub上下载源代码&#xff0c;我…

计算机网络的性能

目录 一、计算机网络的性能指标——宽带 二、计算机网络的性能指标——时延 三、计算机网络的性能指标——时延带宽积 四、计算机网络的性能指标——往返时延 五、计算机网络的性能指标——吞吐量 六、计算机网络的能能指标——利用率 计算机网络的定义&#xff1a;计算机网络时…

策略设计模式

package com.jmj.pattern.strategy;public interface Strategy {void show(); }package com.jmj.pattern.strategy;public class StrategyA implements Strategy{Overridepublic void show() {System.out.println("买一送一");} }package com.jmj.pattern.strategy;p…

力扣日记12.3-【二叉树篇】二叉树的所有路径

力扣日记&#xff1a;【二叉树篇】二叉树的所有路径 日期&#xff1a;2023.12.3 参考&#xff1a;代码随想录、力扣 257. 二叉树的所有路径 题目描述 难度&#xff1a;简单 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根节点到叶子节点的路径…

中序和前/后序遍历构造二叉树———通用做法

1. 前序和中序遍历 **思路&#xff1a;我们每一次一定可以根据递归确定根节点是哪个&#xff0c;就是前序第一个数&#xff0c;然后找中序遍历这个点&#xff0c;看左子树有几个节点&#xff0c;右子树有几个节点&#xff0c;然后就可以根据节点个数&#xff0c;递归左子树和右…

什么是跨站脚本攻击

跨站脚本攻击 1. 定义2. 跨站脚本攻击如何工作3. 跨站脚本攻击类型4. 如何防止跨站脚本攻击 1. 定义 跨站脚本攻击&#xff08;Cross-site Scripting&#xff0c;通常称为XSS&#xff09;&#xff0c;是一种典型的Web程序漏洞利用攻击&#xff0c;在线论坛、博客、留言板等共享…

「C++」位图和布隆过滤器

&#x1f4bb;文章目录 位图概念位图的实现位图的应用 布隆过滤器概念布隆过滤器的哈希函数布隆过滤器的插入布隆过滤器的查找布隆过滤器的删除 &#x1f4d3;总结 位图 概念 所谓位图&#xff0c;就是在每一位bit位上存放某种状态&#xff0c;1就代表存在&#xff0c;0就代表…

SpringSecurity 三更草堂 学习笔记

SpringSecurity从入门到精通 0. 简介 Spring Security 是 Spring 家族中的一个安全管理框架。相比与另外一个安全框架Shiro&#xff0c;它提供了更丰富的功能&#xff0c;社区资源也比Shiro丰富。 一般来说中大型的项目都是使用SpringSecurity 来做安全框架。小项目有Shiro的…

三菱(MITSUBISHI)CNC数据采集

一&#xff0c;概述 前面介绍过&#xff0c;三菱CNC数据采集一般有两种方法&#xff1a; &#xff08;1&#xff09;通过官方A2 API&#xff08;也叫EZSocket&#xff09;进行数据采集&#xff0c;需要安装A2驱动包&#xff08;仅适用于windows系统&#xff09; &#xff08;…

SimpleDataFormat 非线程安全

目录 前言 正文 1.出现异常 2.解决方法1 3.解决方法2 总结 前言 SimpleDateFormat 类是 Java 中处理日期和时间格式化和解析的类&#xff0c;但它并不是线程安全的。这意味着多个线程不能安全地共享一个 SimpleDateFormat 实例进行日期和时间的解析和格式化。当多个…

【JavaScript手撕代码】函数柯里化

函数柯里化 上面的api用的很多&#xff0c;所以都知道是干嘛的使用场景是什么&#xff0c;柯里化用得并不多&#xff0c;所以想手撕之前还是先了解一下它的意义以及用处 什么是柯里化 柯里化Currying又称部分求值&#xff0c;是高阶函数的一种&#xff0c;通常只需要把一部分…

【5G PHY】5G NR 如何计算资源块的数量?

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G算力网络技术标准研究。 博客…

【像素画板】游戏地图编辑器-uniapp项目开发流程详解

嘿&#xff0c;用过像素画板没有哦&#xff0c;相信喜欢绘画的小朋友会对它感兴趣呢&#xff0c;用来绘制像素画非常好看&#xff0c;有没有发现&#xff0c;它是可以用来绘制游戏地图的&#xff0c;是不是很好奇&#xff0c;来一起看看吧。 像素画板&#xff0c;也叫像素画的绘…

C++基础 -34- 输入输出运算符重载

输出运算符重载格式 ostream & operator<<(ostream &out,person a) {cout << a.a << endl;return out; }举例输出运算符重载 #include "iostream"using namespace std;class person {public:person(int a):a(a){}int a; };ostream &…

Go 语言中的反射机制

欢迎大家到我的博客浏览&#xff0c;更好的阅读体验请点击 反射 | YinKais Blog 反射在大多数的应用和服务中并不常见&#xff0c;但是很多框架都依赖 Go 语言的反射机制简化代码。<!--more-->因为 Go 语言的语法元素很少、设计简单&#xff0c;所以它没有特别强的表达能…

51. N 皇后

题目介绍 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方案…