数据结构--栈

一.栈的定义:

        在刷算法题时和解决业务问题时,经常会使用到栈的思想,那么这个栈到底是什么东西呢?其实栈(stack)就是一种特殊的线性表的数据结构,线性表可以任意操作结构中的数据,而且栈不一样,是一种有限制的线性表,我们能操作的只有栈顶元素。好比弹夹子弹装弹以及桶装水的过程,我们只能控制最上面的元素。核心遵循的原则思想就是:“先进后出”/“后进先出”。和线性表一样,也有顺序栈和链式栈两种存储。不同的是,由于栈的限制,一般的操作只有入栈与出栈。

二.栈的各自操作:

        一般的,栈底是固定不变的,而栈顶是活动,为了方便,通常会使用一个变量去描述这个栈顶top,借用“栈顶指针”去称呼top变量。需要注意的是,top并不是一个指针变量,一些教材这里只是为了称呼方便。

2.1 顺序栈的操作

#include<stdio.h>
#include<stdlib.h>
#define maxsize 10
typedef struct{
    int *data;
    int top;//栈顶“指针”
}sstack;

// int isFull(sstack *s);
// int isEmpty(sstack *s);

sstack initStack()
{
    sstack s;
    s.data=(int*)malloc(sizeof(int)*maxsize);
    if(s.data==NULL)
    {
        printf("空间分配失败\n");
    }
    s.top=-1;//top标记的是真正栈顶元素的位置
    //s.top=0;//top标记的是真正栈顶元素上面一个的位置
    return s;
}

//判满
int isFull(sstack *s)
{
    if(s->top==maxsize-1)//if(s->top==maxsize)
    {
        return 1;
    }
    return 0;
}
//入栈
void Push(sstack *s,int k)
{
    if(isFull(s)==1)
    {
        printf("栈满,不能入栈\n");
    }
    else
    {
        s->top++;//s->data[s->top]=k;
        s->data[s->top]=k;//s->top++
        //或s->data[++s->top]=k;//s->data[s->top++]=k;
    }
}

//判空
int isEmpty(sstack *s)
{
    if(s->top==-1)//if(s->top==0)
    {
        return 1;
    }
    return 0;
}

//出栈
void Pop(sstack *s)
{
    if(isEmpty(s)==1)
    {
        printf("栈空,不能出栈\n");
    }
    else
    {
        s->top--;
    }
}

//得到栈顶数据
int getTop(sstack s)
{
    if(isEmpty(&s)==1)
    {
        printf("栈空,没有数据\n");
        return -1;//特殊值
    }
    return s.data[s.top];//return s.data[s.top-1]
}


int main()
{
    sstack s=initStack();
    //传入指针进行函数调用
    Push(&s,1);
    printf("%d\n",getTop(s));
    Push(&s,2);
    Push(&s,3);
    printf("%d\n",getTop(s));

    Pop(&s);
    printf("%d\n",getTop(s));
    return 0;
}

2.2 链式栈的操作

        链栈的各种操作是基于带头结点的单链表实现的,这里选用头插法进行栈顶元素的操作:

#include<stdio.h>
#include<stdlib.h>
//基于带头结点的单链表实现
typedef struct StackNode{
    int data;
    struct StackNode* next;
}sstackNode,*linkstack;

//初始化一个带头结点的栈
linkstack initstack()
{
    sstackNode* s=(sstackNode*)malloc(sizeof(sstackNode));
    if(s==NULL)
    {
        printf("空间分配失败\n");
    }
    s->next==NULL;
    // return s;
}

//入栈(头插法)
linkstack Push(linkstack top,int k)
{
    sstackNode* s=(sstackNode*)malloc(sizeof(sstackNode));
    if(s==NULL)
    {
        printf("空间分配失败\n");
        return top;
    }
    s->data=k;
    s->next=top->next;
    top->next=s;
    return top;
}

//判空
int isEmpty(linkstack top)
{
    if(top->next==NULL){
        return 1;
    }
    return 0;
}
//出栈
linkstack Pop(linkstack top)
{
    if(isEmpty(top)==1)
    {
        printf("栈空,不能出栈\n");
    }
    else
    {
        sstackNode *p=top->next;
        top->next=p->next;
        free(p);
        p=NULL;
    }
    return top;
}

int getTop(linkstack top)
{
    if(isEmpty(top)==1)
    {
        printf("栈空,没有数据\n");
        return -1;//特殊值
    }
    else
    {
        return top->next->data;
    }
}
int main()
{
    linkstack top=initstack();
    top=Push(top,1);
    printf("%d\n",getTop(top));
    top=Push(top,2);
    top=Push(top,3);
    printf("%d\n",getTop(top));

    top=Pop(top);
    printf("%d\n",getTop(top));
    return 0;
}

二.总结:

        栈的基本内容并不多,just-so-so,重点在于如何应用去解决问题,要把握这种“先进后出”/“后进先出”思想,多加练习,才能真正掌握。
        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值