栈基础操作(附加合法出栈题解)《C语言版》

256 阅读4分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路

栈的基本框架图

1.栈的定义

**栈(Stack): **栈是一种特殊的线性表,它只能在一个表的一个固定端进行数据结点的插入和删除操作。

  栈又被称为后进先出(Last in First Out)的线性表,简称LIFO。

2.栈的顺序表实现

 对于顺序表,在C语言中表现为数组,进行栈的定义,需要考虑以下几个点:

1.栈数据的存储方式;

2.栈的大小;

3.栈顶指针。

(1)我们可以定义一个栈的结构体

struct Stack {
    int *stack;
    int top;
};

Stack就是接下来会用到的栈结构体

top即栈顶指针,top=-1表示空栈 

(2)初始化栈

struct Stack* InitStack(int len) {
    struct Stack* p = (struct Stack*)calloc(len, sizeof(struct Stack));
    p->stack = (int*)calloc(len, sizeof(int));
    p->top = -1;
    return p;
}

calloc用来定义p的空间          初始化 top=-1 ;

calloc() 函数用来动态地分配内存空间并初始化为 0,其原型为:
void* calloc (size_t num, size_t size);
calloc() 在内存中动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0。所以它的结果是分配了 num*size 个字节长度的内存空间,并且每个字节的值都是0。
详请calloc的链接

    callochttp://c.biancheng.net/cpp/html/134.htmlicon-default.png?t=LA92http://c.biancheng.net/cpp/html/134.html

(3)找栈头 


int top(struct Stack* p)
{
    return p->stack[p->top];
}

(4)清空栈

void StackClear(struct Stack* stk)
{
	stk->top = -1;
}

只要将栈顶指针初始化即可

(5)判断栈空

bool StackEmpty(struct Stack* p) {
    if (p->top == -1) {
        return true;
    }
    return false;
}

(6)进栈

//进栈
void StackPushStack(struct Stack* stk, int e)
{
	if (stk->top == maxn - 1)printf("栈已满");
	return;
	stk->data[++stk->top] = e;
}

首先判断栈是否满,不满则加入e

(7)出栈

void StackPopStack(struct Stack* stk)
{
	while (stk->top != -1)
	{
		--stk->top;
	}
}

如果为空栈的时候(stk->top=-1),即出栈完毕

源代码

#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>

struct Stack {
    int *stack;
    int top;
};
//初始化栈
struct Stack* InitStack(int len) {                                                 
    struct Stack* p = (struct Stack*)calloc(len, sizeof(struct Stack));
    p->stack = (int*)calloc(len, sizeof(int));
    p->top = -1;
    return p;
}
//找栈头
int top(struct Stack* p)
{
    return p->stack[p->top];
}
//清空栈
void StackClear(struct Stack* stk)
{
    stk->top = -1;
}
//判断栈空
bool StackIsEmpty(struct Stack* stk)
{
    if (stk->top == -1)return true;
    return false;
}
//入栈
void StackPushStack(struct Stack* stk,int e)
{
   
    stk->stack[++stk->top] = e;
}
//出栈
void StackPopStack(struct Stack* stk)
{
    while (stk->top != -1)
    {
        --stk->top;
    }
}

试题小训练

946.验证栈的序列https://leetcode-cn.com/problems/validate-stack-sequences/

思路:将数值加入到栈内,直到栈内的元素和出栈序列的数值相同,相同时指针移动;用栈模拟出栈入栈的过程,当popped中index指向的位置的元素和stack栈顶的元素一致时,出栈 并且 index++,最后判断stack是否为空

视频思路理解 

点此链接效果更好

 源码如下


#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>
struct Stack {
    int* stack;
    int top;
};

struct Stack* InitStack(int len) {
    struct Stack* p = (struct Stack*)calloc(len, sizeof(struct Stack));
    p->stack = (int*)calloc(len, sizeof(int));
    p->top = -1;
    return p;
}

bool StackEmpty(struct Stack* p) {
    if (p->top == -1) {
        return true;
    }
    return false;
}

int top(struct Stack* p) {
    return p->stack[p->top];
}

void pop(struct Stack* p) {
    (p->top)--;
    return;
}

void push(struct Stack* p, int number) {
    (p->top)++;
    p->stack[p->top] = number;
    return;
}
bool validateStackSequences(int* pushed, int pushedSize, int* popped, int poppedSize) {
    struct Stack* a = InitStack(pushedSize);
    int i = 0;
    int j = 0;
    while (i < pushedSize) {
        if (StackEmpty(a)) {
            push(a, pushed[i]);
            i++;
        }
        else {
            while (top(a) == popped[j]) {
                pop(a);
                j++;
                if (StackEmpty(a)) {
                    break;
                }
            }
            push(a, pushed[i]);
            i++;
        }
    }
    while (j < pushedSize) {
        if (popped[j] == top(a)) {
            pop(a);
        }
        j++;
    }
    if (StackEmpty(a)) {
        return true;
    }
    return false;
}
int main()
{

    int m;
    scanf_s("%d", &m);
    int* a = malloc(sizeof(int) * m);
    for (int i = 0; i < m; i++)
    {
        scanf_s("%d", &a[i]);
    }
    int n;
    scanf_s("%d", &n);
    int* b = malloc(sizeof(int) * n);
    for (int i = 0; i < n; i++)
    {
        scanf_s("%d", &b[i]);
    }
    bool c = validateStackSequences(a, m, b, n);
    printf("%d", c);
}

结果为0说明不是正确的出栈序列

结果为1说明是正确的出栈序列 

小插曲

    前几天懒了,玩了一整天游戏,整个人感觉都变废了,一整天都没有刷题;

    我特别钦佩那些能够每天坚持发博客的人,他们每天刷题每天总结;

   今天做了一道中等题差点把我给打趴下,题目都看不懂,差点放弃了了做题,还好感谢大家的支持让我上了一次热榜。

这个是热榜链接blog.csdn.net/weixin_5818…),看着大家的鼓励支持,让我重新燃气了斗志,我不能辜负大家的期望!!!

  同时我也希望可以勉励那些正在坚持着自己梦想的;

路,并不是一帆风顺的总是有许多崎岖的地方;千万不要放弃,咬咬牙就过去了,都坚持了那么久真的甘心放弃嘛?