数据结构-栈

栈是一种特殊的线性表,遵循后进先出(LIFO)原则,仅在栈顶进行插入和删除操作。本文详细介绍了栈的顺序存储和链式存储结构,包括入栈、出栈操作的实现,并提供了C语言的代码示例。顺序存储中,栈顶由top指针标识,链式存储中,栈顶由top指针指向的链表节点表示。此外,还讨论了栈的清空和销毁操作。
摘要由CSDN通过智能技术生成

栈的定义

栈是限定仅在表尾进行插入和删除的线性表。(后进先出)

我们把允许插入和删除的一段=端称为栈顶,另一端称为栈底。

首先,栈是一个线性表,栈的元素具有线性关系。栈特殊的地方在于它的插入和删除的位置有所限定,始终只在栈顶插入,最先插入的只能在栈底。

栈的插入操作叫进栈,栈的删除操作叫出栈。

栈的顺序存储结构的实现

typedef struct 
{
	int maxsize;
	int* top;
    int* base;
}SqStack;

maxsize代表栈的最大容量,top代表栈顶指针变量,base代表栈底的指针变量。

top为栈顶指针,top的初值指向栈底。每当插入一个元素时top加1,弹出一个元素时top减1。

我们也可以这样实现栈

typedef struct 
{
	int data[maxsize];
	int top;
	int stacksize;
}SqStack;

其中top用来标注栈顶的位置。

当空栈时top = -1。

创建一个栈

void init(SqStack* s, int n)
{
    s->base = (int*)malloc(sizeof(int)*n);
    if( !s->base )
     {
        exit(0);
     }
    s->maxsize = n;
    s->top = s->base;
}

最开始时,栈顶就是栈底,此时top = base。

当top = base时,栈为空栈。当top = maxsize 时栈满。

入栈操作

void push(SqStack* s, int a)
{
    if(s->top - s->base == s->maxsize)
    {
        printf("栈满!\n");
        exit(0);
    }
    *s->top++ = a;
}

当top - base = maxsize时,说明栈满了,无法进栈。

也可以用realloc函数增加空间。

出栈操作

int pop(SqStack* s)
{
    
    if(s->top == s->base)
    {
        printf("栈已空\n");
       return;
    }
   return *--s->top;
    
}

出栈操作就是在栈顶取出数据,栈顶指针下移。

*--s->top先将top指针减一,再取出元素,即出栈。这里要注意top指向栈顶的位置是没有存储东西的,要取出的元素是栈顶下面的数据。

计算栈的当前容量

栈的当前容量就是元素的个数,只需要用top - base 即可求出当前元素个数。

注意:指针只能相减不能相加。

清空一个栈和销毁一个栈

清空一个栈就是将栈中的所有元素全部作废,因此我们只需要将s->top的值赋予

给s->base即可,清空以后一个栈变为空栈,但是空间结构不会改变。

销毁一个栈与清空不同,销毁栈需要把它占用的空间释放掉。

void CleanStack(SqStack* s)
{
   s->top = s->base;
}
void DestroyStack(SqStack *s)
{

     int i,len;
     len = s->maxsize;
     for( i = 0;i < len;i++)
     {
         free( s->base);
         s->base++;
     }
     s->base = s->top = NULL;
     s->maxsize = 0;
}

栈的链式存储结构的实现

typedef struct StackNode
{
   ElemType data;               //存放栈的数据
   struct StackNode *next;
}StackNode,*LinkStackPtr;


typedef struct LinkStack
{
    LinkStackPtr top;         //top指针
    int count;                 // 栈元素计数器
}

链栈的操作绝大多数都和单链表类似,只是在插入和删除上特殊一点。

进栈操作

Status Push(LinkStack *s, ElemType e)
{
     LinkStackPtr p = (LinkStackPtr)malloc(sizeof(StackNode));
     p->data = e;
     p->next = s->top;
     s->top = p;
     s->count++;
     return OK;
}

用s作为存储e的新结点。

出栈操作

Status Pop(LinkStack *s,ElemType *e)
{

    LinkStackPtr p;
    if( StackEmpty(*s) )
    {
          return ERROR;
    }
    *e = s->top->data;
    p = s->top;
    s->top = s->top->next;
    free(p);
    s->count--;
    return OK;
}

用变量p来存储要删除的链栈结点,将栈顶指针下移一位,最后释放p。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值