数据结构 - 栈

一.栈的定义

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;
    }
    
}
相关推荐
疯狂打码的少年9 小时前
【数据结构】栈:定义、顺序栈与链式栈
数据结构·笔记
wabs6669 小时前
关于图论【最短路径之Bellman_ford 算法|卡码网94.城市间货物运输的思考】
数据结构·算法·图论·卡码网·bellman_ford·求最短路径
今日无bug9 小时前
JS 数据类型 + 内存分配:从 8 种类型到栈堆模型
javascript·数据结构
wabs66610 小时前
关于哈希表【力扣454.四数相加II的思考】
数据结构·算法·leetcode·散列表
白狐_79810 小时前
408数据结构第7章:查找①——顺序查找、折半查找、分块查找知识总结
数据结构
ShineWinsu10 小时前
对于C++中unordered_map的详细介绍
数据结构·c++·算法·面试·stl·哈希表·unordered_map
lingran__11 小时前
C++ 高阶数据结构:AVL 树万字详解|原理、四种旋转、key‑value 实现、调试校验、set/map/红黑树 底层前置知识
数据结构·c++·二叉搜索树·平衡二叉树·avl树·红黑树前置
疯狂打码的少年12 小时前
【数据结构】顺序表 vs 链表的对比与选择
数据结构·笔记·链表
wabs6661 天前
关于图论【最短路径之Dijkstra算法(堆优化版)|卡码网47.参加科学大会的思考】
数据结构·算法·图论·优先级队列·邻接表·小顶堆·卡码网
yyy(十一月限定版)1 天前
016【入门】双端队列
数据结构·c++