c语言数据结构-栈

 (创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)

目录

初识栈: 

顺序栈:

初始化栈: 

 栈的插入(压栈):

 栈的删除(出栈):

清空栈: 

链栈: 

初始化栈: 

入栈: 

出栈: 

清空栈: 


初识栈: 

(栈的相关操作类似于手枪子弹上膛,装弹时将子弹从上方一个个压入弹夹,开枪时最上面的子弹先被射出)

栈(stack)是限定仅在表尾插入和删除操作的线性表。
允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom)
不含任何数据元素的栈称为空栈 

特点:先进后出,后进先出

 

注意:
1 、栈又被称为后进先出( Last In First Out )的 线性表 ,简称 LIFO 结构
2 、栈的插入操作,称为 进栈 ,也称压栈、入栈( push )
3 、栈的删除操作,称为 出栈 ,也称为弹栈( pop ) 

顺序栈:

顺序栈是利用一组连续存储单元依次存放栈底到栈顶的数据元素 

#define MAX_SIZE 255

typedef struct {
    int id;
    char* name;
}ElementType;

/** 定义栈的顺序存储方式 */
typedef struct SeqStack {
    ElementType elements[MAX_SIZE]; //顺序栈中用来存放数据元素的数组
    int top;                        //栈顶(数组中的下标),如果为-1则证明栈为空
    int length;                     //当前栈的元素个数
}SeqStack;

初始化栈: 

初始化栈时我们需要将栈顶top赋值为-1,这样在后续操作时就可以对top进行加减,便于判断是否为满栈或者空栈

/** 初始化栈 */
void InitSeqStack(SeqStack* seqStack) {
    seqStack->top = -1; //栈顶指向-1的下标
    seqStack->length = 0;
}

 栈的插入(压栈):

顺序栈的入栈操作只需要将数值赋给对应的数组下标即可(先判断是否可以插入) 

/** 向栈中压入元素,返回压入的结果(1/0) */
int PushSeqStack(SeqStack* seqStack, ElementType element) 
{
    //判断是否满栈
    if (seqStack->top == MAX_SIZE - 1)
    {
        printf("满栈,压栈操作失败!");
        return 0;
    }
    seqStack->top++;        //栈顶指针+1,以便加入新的元素
    //将新插入的元素赋值给栈顶
    seqStack->elements[seqStack->top] = element;
    seqStack->length++;
    return 1;
}

 栈的删除(出栈):

/** 以指针方式返回出栈的元素,返回值为出栈的结果(1/0) */
int PopSeqStack(SeqStack* seqStack, ElementType* element) 
{
    if (seqStack->top == -1) 
    {
        printf("空栈,出栈失败!\n");
        return 0;
    }
    //返回栈顶指向的元素
    *element = seqStack->elements[seqStack->top];
    seqStack->top--;
    seqStack->length--;
    return 1;
}

清空栈: 

/** 清空栈 */
void ClearSeqStack(SeqStack* seqStack)
{
    seqStack->top = -1;
    seqStack->length = 0;
}

链栈: 

链栈的结构与链表相似
插入与删除等操作都在链表的头部
即:链栈是一个以top为头结点、从栈顶指向栈底的单链表 

typedef struct
{
    int id;
    const char* name;
}ElementType;

/** 链栈的结点 */
typedef struct StackNode 
{
    ElementType data;           //结点中保存的元素
    struct StackNode* next;    //指向下个结点的指针
}StackNode;

/** 链栈结构 */
typedef struct LinkedStack 
{
    StackNode* top;            //栈顶指针
    int length;                 //链栈的长度(元素个数)
}LinkedStack;

初始化栈: 

void InitLinkedStack(LinkedStack* linkedStack)
{
    linkedStack->top = NULL;
    linkedStack->length = 0;
}

入栈: 

入栈时,和单链表(http://t.csdn.cn/yBFit)相似,只需要将新增的数据的next指向栈顶,然后将栈顶指向新增的数据 

链栈无需判断是否满栈,因为链式结构几乎为无穷大

 

/** 压栈并返回结果 */
int PushLinkedStack(LinkedStack* linkedStack, ElementType element)
{
    //创建一个新结点
    StackNode* newNode = (StackNode*)malloc(sizeof(StackNode));
    newNode->data = element;
    //新结点的next指向当前的栈顶
    newNode->next = linkedStack->top;
    linkedStack->top = newNode;
    linkedStack->length++;
    return 1;
}

出栈: 

出栈有一点特殊,需要新创建一个结点保存要删除的结点数据,然后当top指向下一个结点后,释放新创建的结点,同时也就释放了要删除的结点

 

int PopLinkedStack(LinkedStack* linkedStack, ElementType* element)
{
    //判断栈是否为空
    if (linkedStack->top == NULL) 
    {
        printf("空栈,出栈操作失败!\n");
        return 0;
    }
    //返回栈顶元素
    *element = linkedStack->top->data;
    //创建新结点,记录出栈操作前的栈顶指针
    StackNode* node = linkedStack->top;
    //栈顶指针下移一位
    linkedStack->top = linkedStack->top->next;
    //释放原栈顶空间
    free(node);
    linkedStack->length--;
    return 1;
}

清空栈: 

/** 清空栈-遍历栈中的每个元素并释放结点空间 */
void ClearLinkedStack(LinkedStack* linkedStack)
{
    StackNode* tempNode;
    while (linkedStack->top) 
    {
        tempNode = linkedStack->top;
        //栈顶指向下个元素
        linkedStack->top = linkedStack->top->next;
        free(tempNode);
        linkedStack->length--;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小周不想卷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值