数据结构day03(栈 Stack 顺序栈、链式栈 )内含具体详细代码实现

目录

【1】栈  Stack

1》栈的定义

 2》顺序栈

 2》链式栈

 4》顺序栈的链式栈的区别


【1】栈  Stack

1》栈的定义

栈:是只允许在一端进行插入或删除的线性表,首先栈是一种线性表,但限定这种线性表只能在某一端进行插入和删除操作。

栈顶:线性表允许进行插入删除的一端

栈底:固定的,不允许进行插入和删除的另一端

空栈:不含任何元素的空表


栈又称为后进先出(Last In First Out)的线性表,简称LIFO结构

 2》顺序栈

特性

逻辑结构:线性结构

存储结构:顺序结构

操作:创空栈、入栈、出栈、判空和判满

 创空:

入栈:

出栈:

 代码展示:

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

typedef int data_t;//重定义整型
typedef struct stack//重定义栈节点结构体类型
{
    int maxlen;//栈的最大长度,表示数组元素个数
    data_t *data;//用来指向存放数据的指针相当于数组
    int top;//定义一个变量表示栈顶的下标
} stack_t;

/*创空栈*/
stack_t *Create(int len)//len表示创建栈时的最大元素长度
{
    stack_t *s = (stack_t *)malloc(sizeof(stack_t));//开辟顺序栈结构体的堆区空间
    if (NULL == s)//容错判断
    {
        perror("malloc lost\n");
        return NULL;
    }
    s->data = (data_t *)malloc(sizeof(data_t) * len);//开辟一个堆区空间,让data指针指向该空间,用于存放数据,相当于数组
    if (NULL == s->data)//容错判断
    {
        perror("malloc lost\n");
    }
    //初始化结构体
    s->maxlen = len;//最大元素个数初始化为建栈的长度
    s->top = -1;//初始化栈顶下标为-1
    return s;//返回创建的栈的结构体指针
}

/*判满*/
int Full(stack_t *p)
{
    return p->top + 1 == p->maxlen;//当栈顶元素的下标加一就是数据元素个数 等于最大元素个数时,栈满
}

/*入栈*/
void Push(stack_t *p, int data)//栈的地址和要入栈的数据
{
    if (Full(p))//先判满,容错判断
    {
        perror("In error\n");
    }
    p->top++;//下标先加一,因为初始化时下标为-1,需要将下标加到0下标处,开始入栈,后面也是每进一个数据,栈顶下标都加一
    p->data[p->top] = data;//往加一后的下标位置插入数据
}

/*判空*/
int Empty(stack_t *p)
{
    return p->top == -1;//当栈顶下标的值为-1时说明栈内没有数据,和创空栈时一样
}

/*出栈*/
int Pop(stack_t *p,int top)
{
    if (Empty(p))//判空,容错判断
    {
        perror("Out error\n");
    }
    for(int i = top;i >= 0;i--)//for循环,从栈顶开始向下循环,依次打印栈内数据
    {
        printf("%d ",p->data[i]);
    }
    printf("\n");
}

int main(int argc, char const *argv[])
{
    stack_t *S = Create(5);//开辟空顺序栈
    Push(S, 5);//调用入栈函数
    Push(S, 4);
    Push(S, 3);
    Push(S, 2);
    Push(S, 1);
    printf("出栈: ");
    Pop(S, S->top);//调用出栈函数, 出栈先进后出  1  2  3  4  5
    return 0;
}

 运行结果:

 

 2》链式栈

逻辑结构:线性结构

存储结构:链式存储

顺序栈和链式栈的区别:存储结构不同,实现的方式也不同,顺序栈是用顺序表实现而链式栈是用链表实现。

栈的操作:创空栈、入栈、出栈、判空

入栈:

 

 出栈:

 代码展示:

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

typedef int data_t;
typedef struct node
{
    data_t data;
    struct node *next;
} Node_t, *Node_p;

/*创建一个空栈*/
void Create(Node_p *p) // Node_p 相当于Node_t *,所以 Node_p *p 相当于定义一个二级指针,接受一级指针的地址  p = &top
{
    *p = NULL; //*p = top = NULL;
}

/*入栈*/
void Push(Node_p *p, int data)
{
    Node_p p_new = (Node_p)malloc(sizeof(Node_t)); // 开辟一个新的要入栈的节点
    if (NULL == p_new)
    {
        perror("malloc lost\n");
    }
    p_new->data = data; // 新节点初始化
    p_new->next = *p;//让新节点连接到top栈顶上
    *p = p_new;//让top栈顶移动到新节点处,让新节点成为栈顶
}
/*判空*/
int Empty(Node_p p)
{
    return p == NULL;//当栈顶为空的时候,就是创空栈的时候
}

/*出栈*/
void Pop(Node_p *p)
{
    if (Empty(*p))//判空,容错判断
    {
        perror("Empty\n");
    }
    while (*p != NULL)//当栈顶不是空,就进入循环
    {
        printf("%d ", (*p)->data);//先出栈顶的元素
        Node_p p_del = *p;//定义一个p_del指针指向栈顶
        *p = (*p)->next;//让栈顶向下移动,指向下一个节点
        free(p_del);//释放之前的栈顶节点
        p_del = NULL;//将p_del指针置空
    }
    printf("\n");
}

/*栈的长度*/
int Length(Node_p p)
{
    int len = 0;//定义一个变量保存栈的长度
    while (p != NULL)//当栈顶元素不为空就进入循环
    {
        len++;//让栈的长度加一
        p = p->next;//栈顶指针向下移动,指向下一个节点
    }
    return len;//返回栈的长度
}

int main(int argc, char const *argv[])
{
    Node_p top;//定义一个栈结构体类型的指针
    Create(&top); // top = NULL,创空栈,此时栈里只有一个控制真
    for (int i = 0; i < 5; i++)//循环调用入栈函数
        Push(&top, i);
    printf("栈的长度:%d\n", Length(top));//打印栈的长度
    printf("出栈: ");
    Pop(&top);//调用出栈函数,先入后出

    return 0;
}

运行结果:

 4》顺序栈的链式栈的区别

1> 顺序栈是顺序存储,内存连续,用顺序表实现;链表是链式存储,内存不连续,用链表实现。

2> 顺序栈的长度固定,而链栈不会。


今天的分享就到这里结束啦,如果有哪里写的不好的地方,请指正。
如果觉得不错并且对你有帮助的话请给个三连支持一下吧!

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值