数据结构 - 栈

一.栈的定义

1.栈的分类

栈根据存储结构的不同被分为 顺序栈链式栈

2.栈的结构

①.顺序栈

②.链式栈

top->nex t 即为指向栈顶的指针

3.栈的结构体定义

①.顺序栈

②.链式栈

二.顺序栈的基本运算

0.顺序栈结构体定义

cpp 复制代码
typedef int data_t;

typedef struct
{
    data_t *data;   //指向栈的指针
    int maxlen;     //表示栈的最大长度
    int top;        //栈顶元素的下标,用来指明栈顶的位置
}s

1.创建一个空栈 - Stack_Create

cpp 复制代码
/**
 * @description:                创建一个空栈
 * @param - len     :           栈的最大长度
 * @return          :           指向栈的指针
*/
sqstack_t *Stack_create(int len)
{
    sqstack_t *s;

    /* 1.为栈申请空间 */
    s = (sqstack_t *)malloc(sizeof(sqstack_t));
    if(NULL == s)
    {
        printf("sqstatck create failed!\n");
        return NULL;
    }

    /* 2.为栈内的数据域申请空间 */
    s->data = (data_t *)malloc(len * sizeof(data_t));
    if(NULL == s->data)
        return NULL;

    s->maxlen = len;
    s->top = -1;            //初始化 top = -1 , 则代表栈为空栈
    
    return s;
}

2.清空栈 - Stack_Clear

cpp 复制代码
/**
 * @description:                清空一个栈
 * @param - s       :           要操作的栈的指针
 * @return          :           无
*/
void Stack_Clear(sqstack_t *s)
{
    s->top = -1;
}

3.判断是否为栈空 - Empty_Stack

cpp 复制代码
/**
 * @description:                判断栈是否为空
 * @param - s       :           要操作的栈
 * @return          :           返回 1 则为空 , 否则为非空
*/
int Stack_Empty(sqstack_t *s)
{
    return (s->top == -1 ? 1 : 0);
}

4.判断是否满栈 - Full_Stack

cpp 复制代码
/**
 * @description:                判断栈是否为满
 * @param - s       :           要操作的栈的指针
 * @return          :           1 为满 , 否则为空
*/
int Stack_Full(sqstack_t *s)
{
    return (s->top == s->maxlen-1 ? 1 : 0);
}

5.元素进栈 - Push_Stack

cpp 复制代码
/**
 * @description:            入栈
 * @param - s       :       要操作的栈的指针
 * @param - value   :       要压入的输入
 * @return          :       0 为成功 , 其他为失败
*/
int Stack_Push(sqstack_t *s,data_t value)
{
    /* 1.判断栈是否为满 */
    if(Stack_Full(s))
    {
        printf("stack is already full!\n");
        return -1;
    }


    /* 2.栈顶元素的下标先++ */
    s->top++;

    /* 3.填充数据 */
    s->data[s->top] = value;

    return 0;
}

6.元素出栈 - Pop_Stack

cpp 复制代码
/**
 * @description:            出栈,并返回出栈的元素
 * @param - s   :           要操作的栈的指针
 * @return      :           出栈的元素
*/
int Stack_Pop(sqstack_t *s)
{
    s->top--;

    return s->data[s->top + 1];
}

7.取栈顶元素 - Get_Top

cpp 复制代码
/**
 * @description:            取栈顶的元素
 * @param - s       :       要操作的栈的指针
 * @return          :       栈顶的的元素
*/
int Stack_Get_top(sqstack_t *s)
{
    return (s->data[s->top]);
}

8.释放栈的空间

cpp 复制代码
/**
 * @description:            释放栈的空间
 * @param - s       :       要操作的栈
 * @return          :       无
*/
void Stack_Free(sqstack_t *s)
{
    /* 1.先释放数据域 */
    free(s->data);
    s->data = NULL;

    /* 2.释放栈空间 */
    free(s);
    s = NULL;
}

三.链式栈的基本操作

0.链式栈结构体定义

cpp 复制代码
typedef int data_t;

typedef struct node
{
    data_t data;                //数据域名
    struct node *next;     //指针,指向栈下一个元素
}linkstack_t;

1.创建一个空栈

cpp 复制代码
/**
 * @description:            创建一个空栈
 * @param           :       无
 * @return          :       创建的栈的首结点指针
*/
linkstack_t *Linkstack_Create(void)
{
    linkstack_t *s;

    /* 为栈申请空间 */
    s = (linkstack_t *)malloc(sizeof(linkstack_t));
    if(NULL == s)
    {
        printf("linkstack create error!\n");
        return NULL;
    }
    s->next = NULL;         //初始化头结点

    return s;
}

2.判断栈是否为空

cpp 复制代码
/**
 * @description:            判断是否为空栈
 * @param - s       :       要操作的栈的首结点指针
 * @return          :       1 为成功 ,其他为失败
*/
int Linkstack_Empty(linkstack_t *s)
{
    if(NULL == s->next)
        return 1;
    else
        return 0;
}

3.清空栈

cpp 复制代码
/**
 * @description:            清空栈
 * @param - s       :       要操作的栈的首结点指针
 * @return          :       无
*/
void Linkstack_Clear(linkstack_t *s)
{
    linkstack_t *p;          //r 指向要释放的结点 , p 指向

    p = s->next;

    /* 遍历所有结点,最后一个结点的 p->next 为 NULL */
    while(p)
    {
        s->next = p->next;
        free(p);
        p = s->next;
    }

}

4.入栈

cpp 复制代码
/**
 * @description:            入栈(用单链表的头插实现)
 * @param - s       :       要操作的栈的首结点指针
 * @param - value   :       入栈元素的值
 * @return          :       0 为成功, -1 为失败
 * 
*/
int Linkstack_Push(linkstack_t *s,data_t value)
{
    linkstack_t *p;     //用来指向新创建的结点

    /* 1.创建一个新的结点 */
    p = (linkstack_t *)malloc(sizeof(linkstack_t));
    if(NULL == p)
    {
        printf("malloc error!\n");
        return -1;
    }

    /* 2.给新结点填充数据 */
    p->data = value;

    /* 3.利用单链表的头插,为栈压入结点 */
    p->next = s->next;
    s->next = p;

    return 0;
}

5.出栈

cpp 复制代码
/**
 * @description:            出栈,并返回出栈的元素
 * @param - s       :       要操作的栈的首结点指针
 * @return          :       出栈的元素的值
*/
data_t Linkstack_Pop(linkstack_t *s)
{
    linkstack_t *p;         //指向要出栈的元素
    data_t value;

    p = s->next;            //指向栈顶元素
    value = p->data;        //获取栈顶元素的值

    /* a(i-1) 指向 a(i+1) 即删除了 a(i) */
    s->next = p->next;

    free(p);
    p = NULL;

    return value;

}

6.查看栈顶元素

cpp 复制代码
/**
 * @description:            查看栈顶的元素
 * @param - s       :       要操作的栈的首结点指针
 * @return          :       栈顶的元素
*/
data_t Linkstack_Get_Pop(linkstack_t *s)
{
    return (s->next->data);
}

7.释放栈的空间

cpp 复制代码
/**
 * @description:            释放栈的空间
 * @param - s       :       要操作的栈的首结点指针
*/
void Linkstack_Free(linkstack_t *s)
{
    linkstack_t *p;

    /* 1.初始化 p 指向首结点 */
    p = s;

    /* 2.遍历整个链表 */
    while(p)
    {
        s = s->next;
        free(p);
        p = s;
    }
    
}
相关推荐
X同学的开始1 小时前
数据结构之二叉树遍历
数据结构
AIAdvocate4 小时前
Pandas_数据结构详解
数据结构·python·pandas
jiao000014 小时前
数据结构——队列
c语言·数据结构·算法
铁匠匠匠4 小时前
从零开始学数据结构系列之第六章《排序简介》
c语言·数据结构·经验分享·笔记·学习·开源·课程设计
C-SDN花园GGbond4 小时前
【探索数据结构与算法】插入排序:原理、实现与分析(图文详解)
c语言·开发语言·数据结构·排序算法
CV工程师小林6 小时前
【算法】BFS 系列之边权为 1 的最短路问题
数据结构·c++·算法·leetcode·宽度优先
Navigator_Z6 小时前
数据结构C //线性表(链表)ADT结构及相关函数
c语言·数据结构·算法·链表
还听珊瑚海吗6 小时前
数据结构—栈和队列
数据结构
Aic山鱼6 小时前
【如何高效学习数据结构:构建编程的坚实基石】
数据结构·学习·算法