首页 > 其他分享 >顺序栈————遍历、出栈、入栈

顺序栈————遍历、出栈、入栈

时间:2024-04-25 11:38:23浏览次数:23  
标签:None SeqStack 出栈 入栈 Top Manager 遍历 return 顺序

以数组作为基础实现栈空间(顺序栈)

数组在内存中占用一块连续的空间,也就是数组元素的内存地址是连续的。为了实现栈,一般是把数组头作为栈底,数组头部到数组尾部作为栈的增长方向,也就是用户只在数组尾部对数据进行插入和删除。

  • 为了方便管理顺序栈所以需要构造管理顺序栈信息的结构体类型,用于记录重要参数,如下:
    Bottom:记录栈底地址
    Size :记录栈容量
    Top :记录栈顶元素下标 (为-1则栈空)

image

以下是我的代码:

/*******************************************************************
 *
 *	file name:	SequenceStack.c
 *	author	 :  Dazz
 *	date	 :  2024/04/25
 *	function : 设计一个进制转换程序,使用顺序栈设计一个把十进制数转换为
 *             十六进制数的接口,实现当通过键盘输入一个非负的十进制数,
 *              可以在终端输出对应的十六进制数
 * 	note	 :  None
 *
 *	CopyRight (c)  2024-202x   [email protected]   All Right Reseverd
 *
 * *****************************************************************/

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

// 指的是顺序栈中的元素的数据类型,用户可以根据需要进行修改
typedef int DataType_t;

// 构造记录顺序栈SequenceStack各项参数(栈底地址+栈容量+栈顶元素的下标)的结构体
typedef struct SequenceStack
{
    DataType_t *Bottom; // 记录栈底地址
    unsigned int Size;  // 记录栈容量
    int Top;            // 记录栈顶元素的下标

} SeqStack_t;

/******************************************************
 *
 *  name      : SeqStack_Create
 *	function  : 创建顺序表并对顺序栈进行初始化
 *  argument
 *              @size :顺序栈的容量
 *
 *  retval    : 顺序栈的地址
 *  author    : Dazz
 *  date      : 2024/4/25
 *  note      : None
 *
 * *******************************************************/
SeqStack_t *SeqStack_Create(unsigned int size)
{
    // 1.利用calloc为顺序栈的管理结构体申请一块堆内存
    SeqStack_t *Manager = (SeqStack_t *)calloc(1, sizeof(SeqStack_t));

    if (NULL == Manager)
    {
        perror("calloc memory for manager is failed");
        exit(-1); // 程序异常终止
    }

    // 2.利用calloc为所有元素申请堆内存
    Manager->Bottom = (DataType_t *)calloc(size, sizeof(DataType_t));

    if (NULL == Manager->Bottom)
    {
        perror("calloc memory for Stack is failed");
        free(Manager);
        exit(-1); // 程序异常终止
    }

    // 3.对管理顺序栈的结构体进行初始化(元素容量 + 最后元素下标)
    Manager->Size = size; // 对顺序栈中的容量进行初始化
    Manager->Top = -1;    // 由于顺序栈为空,则栈顶元素的下标初值为-1

    return Manager;
}

/******************************************************
 *
 *  name      : SeqStack_IsFull
 *	function  : 判断顺序栈是否已满
 *  argument
 *              @Manager :顺序栈的地址
 *
 *  retval    : 顺序栈已满返回1,否则返回0
 *  author    : Dazz
 *  date      : 2024/4/25
 *  note      : None
 *
 * *******************************************************/
bool SeqStack_IsFull(SeqStack_t *Manager)
{
    return (Manager->Top + 1 == Manager->Size) ? true : false;
}

/******************************************************
 *
 *  name      : SeqStack_Push
 *	function  : 入栈
 *  argument
 *              @Manager :顺序栈的地址
 *              @Data    :入栈的数据
 *
 *  retval    : 顺序栈已满返回1,否则返回0
 *  author    : Dazz
 *  date      : 2024/4/25
 *  note      : None
 *
 * *******************************************************/
bool SeqStack_Push(SeqStack_t *Manager, DataType_t Data)
{
    // 1.判断顺序栈是否已满
    if (SeqStack_IsFull(Manager))
    {
        printf("SeqStack Full is Full!\n");
        return false;
    }

    // 2.如果顺序栈有空闲空间,则把新元素添加到顺序栈的栈顶
    Manager->Bottom[++Manager->Top] = Data;

    return true;
}

/******************************************************
 *
 *  name      : SeqStack_IsEmpty
 *	function  : 判断顺序栈是否为空
 *  argument
 *              @Manager :顺序栈的地址
 *
 *  retval    : 顺序栈为空返回1,否则返回0
 *  author    : Dazz
 *  date      : 2024/4/25
 *  note      : None
 *
 * *******************************************************/
bool SeqStack_IsEmpty(SeqStack_t *Manager)
{
    return (-1 == Manager->Top) ? true : false;
}

/******************************************************
 *
 *  name      : SeqStack_Pop
 *	function  : 出栈
 *  argument
 *              @Manager :顺序栈的地址
 *
 *  retval    : 出栈的数据
 *  author    : Dazz
 *  date      : 2024/4/25
 *  note      : None
 *
 * *******************************************************/
DataType_t SeqStack_Pop(SeqStack_t *Manager)
{
    DataType_t temp = 0; // 用于存储出栈元素的值

    // 1.判断顺序栈是否为空
    if (SeqStack_IsEmpty(Manager))
    {
        printf("SeqStack is Empty!\n");
        return;
    }

    // 2.由于删除了一个元素,则需要让顺序栈的栈顶元素下标-1
    temp = Manager->Bottom[Manager->Top--];

    return temp;
}

/******************************************************
 *
 *  name      : SeqStack_Print
 *	function  : 遍历并打印每个数据
 *  argument
 *              @Manager :顺序栈的地址
 *
 *  retval    : None
 *  author    : Dazz
 *  date      : 2024/4/25
 *  note      : None
 *
 * *******************************************************/
void SeqStack_Print(SeqStack_t *Manager)
{
    if (-1 == Manager->Top)
    {
        printf("栈为空\n");
        return;
    }

    for (int i = 0; i <= Manager->Top; ++i)
    {
        printf(" Stack Element[%d] = %d\n", i, Manager->Bottom[i]);
    }
}

int main()
{
    SeqStack_t *Manager = SeqStack_Create(100);
    SeqStack_Push(Manager, 999);
    SeqStack_Push(Manager, 888);

    SeqStack_Pop(Manager);
    SeqStack_Pop(Manager);
    SeqStack_Pop(Manager);
    SeqStack_Print(Manager);

    return 0;
}

标签:None,SeqStack,出栈,入栈,Top,Manager,遍历,return,顺序
From: https://www.cnblogs.com/Dazz24/p/18157222

相关文章

  • C语言数据结构:链式栈及其出入栈
    /***********************************************************************************************************实现链式栈一般是以链表作为基础,一般是把链表头部作为栈顶,方便数据的插入和删除,链式栈相当于是一个单向不循环的链表。****Copyright(c)2023-2......
  • 链式栈————出栈、入栈
    以链表作为基础实现栈空间(链式栈)如果打算实现链式栈,一般是以链表作为基础,一般是把链表头部作为栈顶,方便数据的插入和删除(头插+头删),链式栈相当于是一个单向不循环的链表。链式栈要注意的点:出栈要考虑栈是否为空入栈要考虑栈中是否有数据以下是我的代码:/******************......
  • 双向链表和双向循环链表的(创建、插入、删除、遍历)
    V1.02024年4月24日发布于博客园目录目录目录双向链表和双向循环链表的(创建、插入、删除、遍历)设计双向链表的接口创建一个空的双向链表,空链表应该有一个头结点,对链表进行初始化创建新的结点,并对新结点进行初始化(数据域+指针域)创建一个新的结点进行头部插入创建一个新的......
  • 双向循环链表:(创建、插入、遍历、求长、查找、删除、排序、销毁)待测
    目录一、双向循环链表存在的意义二、节点的定义三:实现1:创建链表(即创建一个空链表)2:创建新结点3:遍历4:插入头插入尾插入中间插入一、双向循环链表存在的意义数组这样的结构提供了连续内存的访问和使用,链表是对内存零碎空间的有效组织和使用,双向循环链表增大了访问的自由度。二、......
  • 已知二叉树的前序和中序遍历求后序遍历
    假设二叉树上各结点的权值互不相同且都为正整数。给定二叉树的前序遍历和中序遍历,请你输出二叉树的后序遍历序列。输入格式第一行包含整数N,表示二叉树结点总数。第二行给出二叉树的前序遍历序列。第三行给出二叉树的中序遍历序列。输出格式输出二叉树的后序遍历的第一个数......
  • 已知二叉树的后序和中序遍历求前序遍历
    假设二叉树上各结点的权值互不相同且都为正整数。给定二叉树的后序遍历和中序遍历,请你输出二叉树的前序遍历的最后一个数字。输入格式:第一行包含整数N,表示二叉树结点总数。第二行给出二叉树的后序遍历序列。第三行给出二叉树的中序遍历序列。输出格式输出二叉树的前序遍......
  • 单向链表的插入删除和遍历
    /*********************************************************************************************************** FileName:LinkedList * Author:madman_LX*Contactme:[email protected]* Date :2024/04/22* Function:单向链表的遍历,插......
  • 单向链表遍历插入和删除
    /***********************************************************************************filename:002_单向链表.cauthor:[email protected]:2024/04/22function:单向链表的遍历插入和删除功能的完善note......
  • 【二叉树的前中后序遍历】迭代法
    三种遍历都是用栈维护二叉树前序遍历节点顺序前序遍历模拟前序遍历即可,记录顺序和入栈顺序一致classSolution{publicList<Integer>preorderTraversal(TreeNoderoot){List<Integer>ans=newArrayList<>();if(root==null)returnans;......
  • 【根据前序和中序遍历构造二叉树】栈+迭代 || 递归
    105.从前序与中序遍历序列构造二叉树栈+迭代规律前序遍历中相邻节点u和v,v节点一定是u节点的左节点或者是其自身某个祖先的右节点一个没有右节点的链,中序遍历是从叶子到根,前序遍历是从根到叶子解题思路用一个栈维护前序遍历的节点用一个指针p指向中序遍历的第一个叶子节......