【数据结构】C语言实现顺序栈(附完整运行代码)

这篇具有很好参考价值的文章主要介绍了【数据结构】C语言实现顺序栈(附完整运行代码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🦄个人主页:修修修也

🎏所属专栏:数据结构

⚙️操作环境:Visual Studio 2022

实验 顺序栈的实现,实战项目集,数据结构,数据结构,算法,c语言,学习,开发语言,栈


一.了解项目功能

在本次项目中我们的目标是实现一个顺序栈:

顺序栈使用动态内存分配空间,可以用来存储任意数量的同类型数据.

顺序栈结构体需要包含三个要素:存放数据的数组arr,栈顶元素下标top,栈容量capacity.

顺序栈程序提供的功能有:

  1. 顺序栈的初始化
  2. 顺序栈的销毁
  3. 顺序栈的入栈
  4. 顺序栈的出栈
  5. 顺序栈的长度
  6. 顺序栈判空
  7. 顺序栈取栈顶元素

二.项目功能演示

要编写一个顺序栈项目,首先要明确我们想要达到的效果是什么样,下面我将用vs2022编译器来为大家演示一下顺序栈程序运行时的样子:

顺序栈的C语言实现


三.逐步实现项目功能模块及其逻辑详解

通过第二部分对项目功能的介绍,我们已经对顺序栈的功能有了大致的了解,虽然看似需要实现的功能很多,貌似一时间不知该如何下手,但我们可以分步分模块来分析这个项目的流程,最后再将各部分进行整合,所以大家不用担心,跟着我一步一步分析吧!


!!!注意,该部分的代码只是为了详细介绍某一部分的项目实现逻辑,故可能会删减一些与该部分不相关的代码以便大家理解,需要查看或拷贝完整详细代码的朋友可以移步本文第四部分。


1.实现顺序栈程序菜单

菜单部分的逻辑比较简单,就是利用C语言printf函数打印出这个菜单界面即可。但要注意菜单的标序要和后续switch...case语句的分支相应,以免导致后续执行语句错乱的问题.基础问题就不过多赘述了,代码如下:

该部分功能实现代码如下: 

void STMenu()
{
	printf("**********************************\n");
	printf("******请选择要进行的操作    ******\n");
	printf("******1.顺序栈入栈          ******\n");
	printf("******2.顺序栈出栈          ******\n");
	printf("******3.取栈顶元素          ******\n");
	printf("******4.判断栈空            ******\n");
	printf("******5.查询当前栈长        ******\n");
	printf("******6.清空顺序栈          ******\n");
	printf("******7.销毁顺序栈          ******\n");
	printf("******0.退出顺序栈程序      ******\n");
	printf("**********************************\n");
	printf("请选择:>");

}

2.实现顺序栈程序功能可循环使用

由于我们要实现顺序栈的功能可以反复使用的逻辑,且至少在一开始执行一次,因此我们选择do...while的循环语句来实现这一部分的逻辑.

该部分功能实现代码如下:

int main()
{
	ST st;
	STInit(&st);
    int swi = 0;//创建变量swi作为do...while循环的终止条件,以及switch语句的运行条件
    do          //使用do...while实现
    {
        STMenu();
        scanf("%d", &swi);

        switch (swi)
        {
        case 0:
            STDestroy(&st);
            printf("您已退出程序:>\n");
            // 释放链表内存
            break;

        case 1:
            printf("请输入要入栈的数据:>");
            STDataType pushback_data = 0;
            scanf("%d", &pushback_data);

            STPush(&st, pushback_data);

            printf("已成功入栈:>\n");
            break;

        case 2:
            printf("栈顶元素%d已成功出栈\n", STTop(&st));
            STPop(&st);

            break;

        case 3:
            printf("栈顶元素为:");
            STDataType sttop = STTop(&st);

            printf("%d\n", sttop);

            break;

        case 4:
            if (!STEmpty(&st))
            {
                printf("当前栈不为空\n");
            }
            else
            {
                printf("当前栈为空栈\n");
            }

            break;

        case 5:
            printf("当前栈长为:");
            int stsize = STSize(&st);
            printf("%d\n", stsize);
            break;

        case 6:
            STDestroy(&st);
            STInit(&st);
            printf("顺序栈已清空:>\n");

            break;

        case 7:
            STDestroy(&st);
            printf("顺序栈已销毁:>\n");

            break;

        default:
            printf("输入错误,请重新输入\n");
            break;
        }
    } while (swi);


	return 0;
}

3.创建顺序栈

创建顺序栈成员的结构体应该包括:存放数据的数组arr,栈顶元素下标top,栈容量capacity.

因此我们创建Stack结构体类型时应由一个数组及两个整型组成.

这里的第9行使用的typedef类定义的作用是方便我们后续在使用顺序栈时对存储的数据类型做更改,比如后续我们不想存储int类型数据了,就可以很方便的在这里对数组类型做更改.比如改成char类型,或者double类型,甚至改成任意自己构造的结构类型.

综上,该部分代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once

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

typedef int STDataType;

typedef struct Stack
{
	int *arr;
	int top;
	int capacity;
}ST;

4.初始化顺序栈

初始化顺序栈的逻辑和初始化顺序表一样,我们在初始化时为栈开辟4个数据类型的数组空间,然后将顺序栈的容量改为4,栈顶置为0即可.

该部分的功能实现代码如下:

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

	ps->arr = (STDataType*)malloc(sizeof(STDataType) * 4);
	if (ps->arr == NULL)
	{
		perror("malloc fail::\n");
		return;
	}
	ps->capacity = 4;
	ps->top = 0;   //top表示栈顶元素的下一个
	               //top指向栈顶元素的话,top给-1
	
}

5.顺序栈的入栈

顺序栈在入栈时,需要先判断一下栈内元素是否已满,如果满了则需要给栈扩容.(如下代码5-18行均是在执行顺序栈查满扩容逻辑)

如果没满则将新元素赋值给栈顶指针top,再将top++,使其始终指向栈顶的下一个元素位置.

该部分的功能实现代码如下: 

void STPush(ST* ps, STDataType x)
{
	assert(ps);

	if (ps->top == ps->capacity)//扩容
	{
		STDataType* tmp = (STDataType*)realloc(ps->arr, sizeof(STDataType) * ps->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc fail::\n");
			return;
		}

		ps->arr = tmp;
		ps->capacity *= 2;

	}

	ps->arr[ps->top] = x;
	ps->top++;

}

6.顺序栈的出栈

顺序栈的出栈就相当于顺序表的尾删,那么我们同顺序表一样移动栈顶下标位置即可.

顺序表尾删示意图:实验 顺序栈的实现,实战项目集,数据结构,数据结构,算法,c语言,学习,开发语言,栈

该部分的功能实现代码如下: 

void STPop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));

	ps->top--;
}

7.顺序栈取栈顶元素

根据我们之前的设定,栈为空时top=0:

实验 顺序栈的实现,实战项目集,数据结构,数据结构,算法,c语言,学习,开发语言,栈

那么当栈中进入一个元素时,top++后top=1,而栈顶元素a1的下标等于0,所以我们的top设计其实是指向栈顶元素的下一个位置的:

实验 顺序栈的实现,实战项目集,数据结构,数据结构,算法,c语言,学习,开发语言,栈

因此在取栈顶函数中,我们要返回的栈顶数组下标应该是top-1.

该部分的功能实现代码如下: 

STDataType STTop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));

	return ps->arr[ps->top - 1];
}

8.顺序栈的长度

因为top指向的是栈顶元素的下一个位置,因此top的大小正好是栈的长度,所以求栈长函数我们对ps断言后可以直接返回top.

该部分的功能实现代码如下:

int STSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

9.顺序栈的判空

顺序栈判空的逻辑是:如果栈为空返回true(真),否则返回false(假).

因此我们还是拿top来判断,如果top=0,会return true,意味着栈为空.

否则会return false,意味着栈不为空.

该部分的功能实现代码如下:

bool STEmpty(ST* ps)//判空,为空则真
{
	assert(ps);

	return ps->top==0;
}

10.顺序栈的销毁

当我们使用完顺序栈想要退出程序时,就应该将之前动态开辟的内存释放掉,还给操作系统.即销毁顺序栈.

我们使用free()函数释放掉之前动态开辟的数组arr,然后将arr置为空指针,最后将top,capacity的值置为0即可.

该部分的功能实现代码如下:

void STDestroy(ST* ps)
{
	assert(ps);

	free(ps->arr);
	ps->arr = NULL;
	ps->top = 0;
	ps->capacity = 0;

}

四.项目完整代码

我们将程序运行的代码分别在三个工程文件中编辑,完整代码如下:

test.c文件

#include"Stack.h"

int main()
{
	ST st;
	STInit(&st);
    int swi = 0;//创建变量swi作为do...while循环的终止条件,以及switch语句的运行条件
    do          //使用do...while实现
    {
        STMenu();
        scanf("%d", &swi);

        switch (swi)
        {
        case 0:
            STDestroy(&st);
            printf("您已退出程序:>\n");
            // 释放链表内存
            break;

        case 1:
            printf("请输入要入栈的数据:>");
            STDataType pushback_data = 0;
            scanf("%d", &pushback_data);

            STPush(&st, pushback_data);

            printf("已成功入栈:>\n");
            break;

        case 2:
            printf("栈顶元素%d已成功出栈\n", STTop(&st));
            STPop(&st);

            break;

        case 3:
            printf("栈顶元素为:");
            STDataType sttop = STTop(&st);

            printf("%d\n", sttop);

            break;

        case 4:
            if (!STEmpty(&st))
            {
                printf("当前栈不为空\n");
            }
            else
            {
                printf("当前栈为空栈\n");
            }

            break;

        case 5:
            printf("当前栈长为:");
            int stsize = STSize(&st);
            printf("%d\n", stsize);

            break;

        case 6:
            STDestroy(&st);
            STInit(&st);
            printf("顺序栈已清空:>\n");

            break;

        case 7:
            STDestroy(&st);
            printf("顺序栈已销毁:>\n");

            break;

        default:
            printf("输入错误,请重新输入\n");

            break;
        }
    } while (swi);

	return 0;
}

  Stack.c 文件

#include"Stack.h"

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

	ps->arr = (STDataType*)malloc(sizeof(STDataType) * 4);
	if (ps->arr == NULL)
	{
		perror("malloc fail::\n");
		return;
	}
	ps->capacity = 4;
	ps->top = 0;   //top表示栈顶元素的下一个
	               //top指向栈顶元素的话,top给-1
	
}

void STDestroy(ST* ps)
{
	assert(ps);

	free(ps->arr);
	ps->arr = NULL;
	ps->top = 0;
	ps->capacity = 0;

}

void STPush(ST* ps, STDataType x)
{
	assert(ps);

	if (ps->top == ps->capacity)//扩容
	{
		STDataType* tmp = (STDataType*)realloc(ps->arr,sizeof(STDataType)*ps->capacity*2);
		if (tmp == NULL)
		{
			perror("realloc fail::\n");
			return;
		}

		ps->arr = tmp;
		ps->capacity *= 2;

	}

	ps->arr[ps->top] = x;
	ps->top++;

}

void STPop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));

	ps->top--;
}

int STSize(ST* ps)
{
	assert(ps);

	return ps->top;
}

bool STEmpty(ST* ps)//判空,为空则真
{
	assert(ps);

	return ps->top==0;
}

STDataType STTop(ST* ps)
{
	assert(ps);
	assert(!STEmpty(ps));

	return ps->arr[ps->top - 1];
}

void STMenu()
{
	printf("**********************************\n");
	printf("******请选择要进行的操作    ******\n");
	printf("******1.顺序栈入栈          ******\n");
	printf("******2.顺序栈出栈          ******\n");
	printf("******3.取栈顶元素          ******\n");
	printf("******4.判断栈空            ******\n");
	printf("******5.查询当前栈长        ******\n");
	printf("******6.清空顺序栈          ******\n");
	printf("******7.销毁顺序栈          ******\n");
	printf("******0.退出顺序栈程序      ******\n");
	printf("**********************************\n");
	printf("请选择:>");
}

Stack.h文件

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once

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

typedef int STDataType;

typedef struct Stack
{
	int *arr;
	int top;
	int capacity;
}ST;

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

void STPush(ST* ps, STDataType x);
void STPop(ST* ps);

int STSize(ST* ps);

bool STEmpty(ST* ps);//判空,为空则真

STDataType STTop(ST* ps);

void STMenu();

结语

希望这篇顺序栈的C语言实现详解能对大家有所帮助,欢迎大佬们留言或私信与我交流.

学海漫浩浩,我亦苦作舟!关注我,大家一起学习,一起进步!

相关文章推荐

【数据结构】什么是栈?

【数据结构】C语言实现顺序表万字详解(附完整运行代码)

【数据结构】C语言实现单链表万字详解(附完整运行代码)

【数据结构】C语言实现带头双向循环链表万字详解(附完整运行代码)

【实用编程技巧】不想改bug?初学者必须学会使用的报错函数assert!(断言函数详解)


实验 顺序栈的实现,实战项目集,数据结构,数据结构,算法,c语言,学习,开发语言,栈

数据结构栈与队列篇思维导图:

实验 顺序栈的实现,实战项目集,数据结构,数据结构,算法,c语言,学习,开发语言,栈文章来源地址https://www.toymoban.com/news/detail-861891.html

到了这里,关于【数据结构】C语言实现顺序栈(附完整运行代码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 『初阶数据结构 • C语言』⑦ - 静态顺序表详解(附完整源码)

    本章内容 1.什么是线性表 2.什么是顺序表  3.静态顺序表结构的定义 4.静态顺序表的函数接口实现 5.静态顺序表的问题及思考     线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、

    2024年02月15日
    浏览(44)
  • 数据结构之顺序表的实现(详解!附完整代码)

    线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构 常见的线性表:顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上存

    2024年02月04日
    浏览(40)
  • 数据结构进阶篇 之 【二叉树顺序存储(堆)】的整体实现讲解(赋完整实现代码)

    做人要谦虚,多听听别人的意见,然后记录下来,看看谁对你有意见 3.1 向下调整算法 AdJustDown 3.2 向上调整算法 AdJustUP 3.3 堆的创建 3.3.1 向上建堆 3.3.2 向下建堆 3.3.3 堆的初始化与销毁 3.3.4 堆的插入(压栈) 3.3.5 取堆顶的数据 3.3.6 堆的删除 3.3.7 堆的数据个数 3.3.8 堆的判空

    2024年04月17日
    浏览(73)
  • 【数据结构】C语言实现顺序栈

    大家好,很高兴又和大家见面啦!!! 在上一个篇章中,我们介绍了栈的基本概念,以及栈中的重要术语。通过介绍我们知道了栈的本质也是一种线性表,只不过它是一种操作受限的线性表。因此栈的实现方式与线性表的实现实际上是大同小异的。下面我们就来介绍一下如何

    2024年01月19日
    浏览(42)
  • 【数据结构】C语言实现顺序表

    顺序表是用顺序存储方式存放的线性表(可以理解为数组的存储方式),表中的元素在内存中彼此相邻。 静态存储:在定义时就确定了顺序表的大小,并且之后顺序表的大小不会改变(即使之后空间不够用了,也无法增加) 动态存储:线性表的大小可以根据需要更改(顺序

    2024年02月08日
    浏览(42)
  • 数据结构顺序表(C语言实现)

            从本章开始就是开始数据结构的开端,本章将会写出数据结构中的顺序表的代码实现,多会以注释的方法来描述一些细节(注释是我们程序员必须常用的工具)。         话不多说安全带系好,发车啦(建议电脑观看)。 附:红色,部分为重点部分;蓝颜色为需

    2024年02月10日
    浏览(52)
  • 顺序表—C语言实现数据结构

    本期带大家一起来用C语言代码实现顺序表🌈🌈🌈 顺序表是一段物理地址连续的存储单元,依次存储数据元素的线性结构。分为静态顺序表与动态顺序表。 🍊 🍋 🍒 静态顺序表 :使用定长数组用来存储数据 优点 :操作简单,代码实现容易 缺点 :定长数组很受限制,数

    2023年04月24日
    浏览(39)
  • 【数据结构】C语言实现顺序表(超级详细)

    目录 概念及结构 接口函数实现 顺序表的初始化 容量判断  顺序表尾插  顺序表尾删 顺序表头插 顺序表头删 顺序表查找 顺序表指定位置插入 顺序表指定位置删除 打印顺序表 销毁顺序表 顺序表完整代码 顺序表作为线性表的一种,它是用一段 物理地址连续的存储单元依次

    2024年04月10日
    浏览(37)
  • 【C语言数据结构】模拟·顺序表·总项目实现

    💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃 个人主页 :阿然成长日记 👈点击可跳转 📆 个人专栏: 🔹数据结构与算法🔹C语言进阶 🚩 不能则学,不知则问,耻于问人,决无长进 🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍 我在上一篇博客中,

    2024年02月15日
    浏览(42)
  • 【数据结构初阶】二、 线性表里的顺序表(C语言实现顺序表)

    ========================================================================= 相关代码gitee自取 : C语言学习日记: 加油努力 (gitee.com)  ========================================================================= 接上期 : 【数据结构初阶】一. 复杂度讲解_高高的胖子的博客-CSDN博客  =======================================

    2024年02月08日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包