【数据结构】栈的实现(链式栈)

server/2024/11/13 9:26:27/

文章目录

  • 栈的实现(链式栈)
    • 栈的定义
    • 初始化栈
    • 进栈
    • 判断是否为空栈
    • 出栈
    • 销毁栈
    • 获取栈顶元素
    • 获取栈的长度
    • 栈的打印
  • 完整代码(包括测试代码)
    • Stack.h
    • Stack.c
    • test.c

栈的实现(链式栈)

首先新建一个工程:

Stack.h(链式栈的类型定义、接口函数声明、引用的头文件)
Stack.c(链式栈接口函数的实现)
test.c(主函数、测试栈各个接口功能)

完整的代码放在后面(包括测试代码),这里就不会展示测试的效果图。大家可以自己别敲边按测试代码测试。图解会写的很详细的,么么😙

栈的定义

typedef int ElemType;		/* 链栈结点结构 */
typedef struct StackNode
{ElemType data;struct StackNode* next;
}StackNode;/* 链栈结构 */
typedef struct
{StackNode* top;int count;
}LinkStack;

初始化栈

在这里插入图片描述

// 初始化栈
LinkStack* Init()
{// 注意要给链栈分配内存LinkStack* p = (LinkStack*)malloc(sizeof(LinkStack));if (p == NULL){perror("malloc fail");exit(-1);}p->top = NULL; // 链栈的空其实就是 top=NULL 的时候p->count = 0;return p;
}

进栈

在这里插入图片描述

// 进栈
void push(LinkStack* stack, ElemType x)
{assert(stack);StackNode* s = (StackNode*)malloc(sizeof(StackNode));if (s ==NULL){perror("malloc fail");exit(-1);}s->data = x;s->next = stack->top; stack->top = s; stack->count++;
}

判断是否为空栈

这里可以用count是否等于0判断,也可以用stack->top=NULL来判断都可以。

// 判断是否为空栈
bool isEmpty(LinkStack* stack)
{assert(stack);return  stack->count == 0;
}

出栈

在这里插入图片描述

// 出栈
void pop(LinkStack* stack)
{assert(stack);if (isEmpty(stack))return ;StackNode* q = stack->top;stack->top = stack->top->next;free(q); q = NULL;stack->count--;}

销毁栈

这里需要二级指针才能置空stack,但是我为了整体的美观,我们这里每次使用完后,在函数外面主动置空 plist。

// 销毁栈
void destroy(LinkStack* stack)
{assert(stack);StackNode* p = stack->top;StackNode* q;while (p){q = p;p = p->next;free(q);}stack->count = 0;q = NULL;free(stack);//stack = NULL;//需要主动释放置空,不然要使用二级指针}

获取栈顶元素

// 获取栈顶元素
ElemType getTop(LinkStack* stack)
{assert(stack);if (stack->top == NULL)exit(-1);elsereturn 	stack->top->data;}

获取栈的长度

// 获取栈的长度
int getLength(LinkStack* stack)
{assert(stack);return stack->count;
}

栈的打印

同顺序栈一样写在测试test.c文件中。

完整代码(包括测试代码)

Stack.h

#pragma once
#include<stdio.h>	
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int ElemType;		/* 链栈结点结构 */
typedef struct StackNode
{ElemType data;struct StackNode* next;
}StackNode;/* 链栈结构 */
typedef struct
{StackNode* top;int count;
}LinkStack;// 初始化栈
LinkStack* Init();
// 进栈
void push(LinkStack* stack, ElemType x);
// 判断是否为空栈
bool isEmpty(LinkStack* stack);
// 出栈
void pop(LinkStack* stack);
// 销毁栈
void destroy(LinkStack* stack);
// 获取栈顶元素
ElemType getTop(LinkStack* stack);
// 获取栈的长度
int getLength(LinkStack* stack);

Stack.c

#define _CRT_SECURE_NO_WARNINGS 1#include"Stack.h"// 初始化栈
LinkStack* Init()
{// 注意要给链栈分配内存LinkStack* p = (LinkStack*)malloc(sizeof(LinkStack));if (p == NULL){perror("malloc fail");exit(-1);}p->top = NULL; // 链栈的空其实就是 top=NULL 的时候p->count = 0;return p;
}// 进栈
void push(LinkStack* stack, ElemType x)
{assert(stack);StackNode* s = (StackNode*)malloc(sizeof(StackNode));if (s ==NULL){perror("malloc fail");exit(-1);}s->data = x;s->next = stack->top; stack->top = s; stack->count++;
}// 判断是否为空栈
bool isEmpty(LinkStack* stack)
{assert(stack);return  stack->count == 0;
}// 出栈
void pop(LinkStack* stack)
{assert(stack);if (isEmpty(stack))return ;StackNode* q = stack->top;stack->top = stack->top->next;free(q); q = NULL;stack->count--;}// 销毁栈
void destroy(LinkStack* stack)
{assert(stack);StackNode* p = stack->top;StackNode* q;while (p){q = p;p = p->next;free(q);}stack->count = 0;q = NULL;free(stack);//stack = NULL;//需要主动释放置空,不然要使用二级指针}// 获取栈顶元素
ElemType getTop(LinkStack* stack)
{assert(stack);if (stack->top == NULL)exit(-1);elsereturn 	stack->top->data;}// 获取栈的长度
int getLength(LinkStack* stack)
{assert(stack);return stack->count;
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Stack.h"int main()
{LinkStack* plist = Init();push(plist, 1);push(plist, 2);push(plist, 3);push(plist, 4);push(plist, 5);while (!isEmpty(plist)){printf("%d ", getTop(plist));pop(plist);}printf("\n");int len=getLength(plist);printf("%d\n", len);bool b = isEmpty(plist);if (b){printf("true\n");}else{printf("false\n");}destroy(plist);//主动置空plist = NULL;return 0;
}

http://www.ppmy.cn/server/41859.html

相关文章

记一次跨域问题

线上跨域问题&#xff0c;在自己配置确认没问题下&#xff0c;要及时找运维看看是不是nginx配置问题。 两个方面&#xff1a; 项目代码 nginx配置 SpringBoot 解决跨域问题的 5 种方案&#xff01; SpringBoot解决CORS跨域问题 SpringBoot-实现CORS跨域原理及解决方案

itext5.5.13 PDF预览权限问题

PdfUtils.htFile.createNewFile&#xff08;&#xff09; createNewFile 创建文件错误错误原因方式一方式二实例代码-生成PDF表格数据 createNewFile 创建文件错误 ht getResourceBasePath() "\\templates\\ht.pdf"; htFile new File(ht);代码含义是创建源文件路…

LeetCode73.矩阵置零

题目链接&#xff1a; 73. 矩阵置零 - 力扣&#xff08;LeetCode&#xff09; 分析&#xff1a;普通的模拟问题&#xff0c;我们按照题目的要求进行模拟&#xff0c;把需要的位置置0即可。 算法思路&#xff1a;题目要求原地计算&#xff0c;所以迁移这个矩阵是不现实的。这…

yaml配置文件的在深度学习中的简单应用

1 .创作灵感 小伙伴们再阅读深度学习模型的代码的时候&#xff0c;经常会遇到yaml格式的配置文件。用这个配置文件是因为我们在训练模型的时候会涉及很多的参数&#xff0c;如果这些参数东一个&#xff0c;西一个&#xff0c;我们调起来的时候就会很不方便&#xff0c;所以用y…

vue3和vite

vue3 1、vue3使如何实现效率提升的 客户端渲染效率比vue2提升了1.3~2倍 SSR渲染效率比vue2提升了2~3倍 1.1、静态提升 解释&#xff1a; 1. 对于静态节点&#xff08;如&#xff1a;<h1>接着奏乐接着舞</h1>&#xff09;&#xff0c;vue3直接提出来了&#xff…

GIN框架_请求参数

请求参数 1. Get请求参数 使用Get请求传参时&#xff0c;类似于这样 http://localhost:8080/user/save?id11&namezhangsan。 如何获取呢&#xff1f; 1.1 普通参数 request url: http://localhost:8080/user/save?id11&namezhangsan r.GET("/user/save&qu…

收藏与品鉴:精酿啤酒的艺术之旅

啤酒&#xff0c;这一古老的酒精饮品&#xff0c;不仅是人们生活中的日常饮品&#xff0c;更是一种艺术和文化的载体。对于Fendi club啤酒而言&#xff0c;收藏与品鉴更是一门深入骨髓的艺术之旅。 Fendi club啤酒的收藏&#xff0c;不仅仅是简单的存放和保管&#xff0c;而是一…

Leecode热题100---15:三数之和为零

题目&#xff1a; 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。 请你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的…