数据结构(三)——栈(顺序栈与链栈)

一 栈的定义

栈是一种具有后进先出(Last-In-First-Out,LIFO)特性的数据结构,只能在一端进行插入和删除操作,
该一端通常称为栈顶。



二 顺序栈

1、定义

顺序栈是一种使用数组结构实现的栈。它的特点是可以在数组的一端进行元素的插入(入栈)和删除
(出栈)操作。通过维护一个栈顶指针来标记栈顶元素的位置,每次入栈时,栈顶指针向上移动一位;
每次出栈时,栈顶指针向下移动一位。顺序栈的实现比较简单,但是容量固定,当栈中元素个数达到容
量限制时,会导致栈满。

2、代码示例

用数组表示栈空间,两个变量代表入栈元素以及出栈元素的位置。通过对两个元素的合理使用数组空间
实现栈的功能。

头文件

/*===============================================
*   文件名称:seqstack.h
*   创 建 者: 
*   创建日期:2023年08月09日
*   描    述:
================================================*/
#ifndef _SEQSTACK_H
#define _SEQSTACK_H
#define SIZE 1024
typedef int seqstack_data_t;  // int 类型取别名

// 定义栈结构体类型
typedef struct seq_stack
{
    seqstack_data_t data[SIZE];
    int  top;
}seqstack , *pseqstack;

//创建
pseqstack init_seqstack();

//入栈
int  input_seqstack(pseqstack S , seqstack_data_t value); 

//出栈
int out_seqstack(pseqstack S);

//判空
int empty_seqstack(pseqstack S );


//判满
int full_seqstack(pseqstack S);

#endif

功能代码

/*===============================================
*   文件名称:seqstack.c
*   创 建 者:  
*   创建日期:2023年08月09日
*   描    述:
================================================*/
#include <stdio.h>
#include "seqstack.h"
#include <stdlib.h>
//创建
pseqstack init_seqstack()
{

	//开辟空间
    pseqstack S = (pseqstack) malloc(sizeof(seqstack));
    if( NULL == S )
        return NULL;
        
    S->top = -1;//栈顶top初始化为-1
    return S;
}

//入栈
int  input_seqstack(pseqstack S , seqstack_data_t value)
{

//判定条件
    if( NULL == S )
        return -1;
    if( 0 == full_seqstack(S))
        return -2;
        
    S->data[++(S->top)] = value ;//插入元素,并且栈顶top+1;
    return 0;
    
}

//出栈
int out_seqstack(pseqstack S)
{
    
    //判定条件
    if( NULL == S )
        return -1;
    if( 0 == empty_seqstack(S))
        return -2;

    return S->data[(S->top)--];//返回栈顶元素,并且top-1;

}

//判空
int empty_seqstack(pseqstack S )
{

    if( NULL == S )
        return -1;
    if( -1 == S->top ) // top为-1则为空
        return 0;
    else 
        return 1;
}


//判满
int full_seqstack(pseqstack S)
{
    if( NULL == S )
        return -1;
        
    if( SIZE-1 == S->top )  // top等于栈长度则为满
        return 0;
    else
        return 1;

}


测试代码

/*===============================================
*   文件名称:main.c
*   创 建 者:  
*   创建日期:2023年08月09日
*   描    述:
================================================*/
#include <stdio.h>
#include "seqstack.h"
int main(int argc, char *argv[])
{ 
    
   // 创建顺序栈
    pseqstack S = init_seqstack();
    if( NULL == S )
    {
        puts("init err ");
        return -1;
    }

    //入栈
    puts("入栈顺序");
    for( int i = 0 ; i < 10 ; i++ )
    {
        printf("%d ",i+1);
        if( 0 != input_seqstack(S,i+1))
        {
            puts("input err");
            return -1;
        }
    }
    puts("");

    //出栈
    int ret= 0;
    puts("出栈顺序");
    while( 0 != empty_seqstack(S) )
    {
        if( 0 > (ret = out_seqstack(S)))
        {
            puts("out err");
            return -1;
        }
        printf("%d ", ret);
    }
    puts("");



    return 0;
}

3、运行结果


在这里插入图片描述





三 链栈

1、定义

链栈是一种使用链表结构实现的栈。它的特点是可以在链表的头部进行元素的插入和删除操作。链栈不
需要预先指定容量,可以动态地分配内存,但是每个结点都需要额外的指针来指向下一个结点,相对而
言,空间消耗会更大一些。

2 、代码示例

对链表加以限制,实现栈的功能。通过头插入节点和头弹出节点,实现栈后进先出的功能。

头文件

/*===============================================
*   文件名称:chstack.h
*   创 建 者: 
*   创建日期:2023年08月09日
*   描    述:
================================================*/
#ifndef _CHSTACK_H
#define _CHSTACK_H

typedef int chstack_data;  //给int类型取别名,方便修改链栈数据类型

//定义链栈节点类型
typedef struct ch_stack
{
    chstack_data data;
    struct ch_stack * next;
}chstack,*pchstack;

//创建
pchstack init_chstack();

//入栈
int input_chstack(pchstack H , chstack_data value );

//出栈
int out_chstack(pchstack H);

//判空
int empty_chstack(pchstack H);

#endif

功能代码


/*===============================================
*   文件名称:chstack.c
*   创 建 者:    
*   创建日期:2023年08月09日
*   描    述:
================================================*/
#include <stdio.h>
#include <stdlib.h>
#include "chstack.h"

//创建
pchstack init_chstack()
{

	//开辟空间为链栈头节点
    pchstack H = (pchstack)malloc(sizeof(chstack));
    if( NULL == H )
        return NULL;
        
    H->next = NULL ;//初始化头节点的next为NULL
    return H;
}

//入栈
int input_chstack(pchstack H , chstack_data value )
{
    if( NULL == H )
        return -1;
    
    //开辟一个节点空间装插入的数据 
    pchstack L = (pchstack)malloc(sizeof(chstack));
    if( NULL == L )
        return -1;

	//将节点通过头插的方式插入链栈
    L->next = H->next; // 新节点的next指向头节点的next
    H->next = L ;     //头节点的next指向新节点
    L->data = value;  //将插入的值给予新节点
    
    return 0;
}

//出栈
int out_chstack(pchstack H)
{

    if( NULL == H )
        return -1;
    if( 0 == empty_chstack(H))
        return -2;

	//从链栈头出,达到后进先出的效果
    pchstack p = H->next; //定义一个p临时保存需要出栈的节点
    H->next = p->next;  // 断开头节点与需要出栈的节点,头节点链接到出栈节点的下一个节点
    chstack_data t = p->data; // 临时保存出栈节点的数据
    free(p); // 释放出栈的节点
    p = NULL;
    return t;

}

//判空
int empty_chstack(pchstack H)
{
    if( NULL == H )
        return -1;

    if( NULL == H->next ) // 如果头节点的下一个节点为空,则,链栈为空
        return 0;
    else 
        return 1;

}


测试代码

/*===============================================
*   文件名称:main.c
*   创 建 者: 肖建军   
*   创建日期:2023年08月09日
*   描    述:
================================================*/
#include <stdio.h>
#include "chstack.h"
int main(int argc, char *argv[])
{ 
    //创建
    pchstack H = init_chstack();
    if( NULL == H )
    {
        puts("init err");
        return -1;
    }

    //入栈
    puts("入栈");
    for( int i = 0 ; i < 10 ; i++ )
    {
        printf("%d " , i+1);
        if( 0 != input_chstack(H , i+1))
        {
            puts("input err");
            return -1;
        }
    }
    puts("");

    //出栈
    puts("出栈");
    int ret = 0 ;
    while( 0 != empty_chstack(H))
    {
        if( 0 > (ret = out_chstack( H )))
        {
            puts("out err");
            return -1;
        }
        printf("%d ",ret);
    }
    puts("");


    return 0;
} 

3、运行结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值