数据结构——栈的相关代码及介绍

什么是栈

​ 乍一听栈,似乎脑中会浮现出一座客栈,或是一个栈桥的样子,这条栈桥又窄又长,无数的同学在路过的时候都失足跌落…

​ 好啦,不开玩笑了。前面我们学过了顺序表,也学习了链表,如今的栈只是基于这两种数据结构的应用而已,不过在我看来,栈还真的像一座窄桥,你不过,我不过,我不出,你也别想出.

​ 言归正传,什么是栈呢?从生活实际中获取实例是理解的最好方式,那么生活中哪里应用到了栈呢?

栈的定义

​ 咱先不谈定义,谈谈实例。

​ 在我们使用浏览器浏览新闻的时候,突然发现,一则广告,wow! XXX代言,下载就能十连抽,不爆sss不开局!点进去一看,这骗的太没有诚意了,这明星图片都给p虚了,这时候如果我们要拂袖而去,怎么办呢?如果是跳转的页面那我们点击回退按钮就行了,对吧。

​ 这个回退按钮其实就是浏览器在内存上应用的一种栈的存储结构,就像我们使用的word或画图中的撤销,我们撤销是一步步的回退,从当前的操作一步步移动到以前的。又比如自动手枪中的子弹,我们依次射击出去,最后放入的子弹反而第一个射出,这些先进后出的情况其实都是栈在实际中的应用。

​ 下面我们来看一下栈的定义吧

取自百度百科

​ 栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

​ 划重点!运算受限 线性表 表尾插入 表头删除 插入是入栈 删除叫出栈

我们一般把允许插入和删除的一端称为栈顶(top),另一端称为栈底(bottom),不含任何数据元素的栈叫做空栈,栈又称为先进后出(Last In First Out)的线性表,简称LIFO结构,下次见到可不要被唬到了,当时我第一眼看到在想:高级!了解后:原来不过如此…所以术语也要了解,这样咱们就可以拿它去糊别人了…

  • 首先要明确栈是一种线性表
    • 线性表有两种:顺序表 链表 栈同样如此
顺序栈

顺序栈类型描述

#define MaxSize 100//顺序栈的最大元素数
typedef struct{
    int elem[MaxSize];
    int top;//栈顶指针,其实就是数组下标
}SeqStack;

创建空栈

SeqStack *InitStack(){
    SeqStack *s;
    s = (SeqStack*)malloc(sizeof(SeqStack));
    s->top = -1;//空栈栈顶指针为-1 判断是否为空栈据此即可
    return s;
}

入栈

int Push(SeqStack *s , int x){
    //先判断是否栈满
    if(s->top == MaxSize - 1){
		printf("栈已满");
       	return 0;
    }
    //如果栈不满则进栈
    else{
        s->top++;
		s->elem[s->top] = x;
        return 1;
    }
}

出栈

int Pop(SeqStack *s , int *x){
    //x是用来存储删除的内容的
    //栈空不能出栈
    if(s->top == -1){
        printf("栈已满");
        return 0;
    }
    else{
        *x = s->elem[s->top];
        s->top--;
        return 1;
    }
}

栈的存储空间有限,如果我们开辟两个栈空间,有时候我们会发现,第一个栈空间已经用完,可能第二个空间还只有一两个元素,因此,我们可以从栈的表头,表尾同时进行两个栈的存储

因为需要两个指针,所以栈的结构也要发生一定的变化

我们需要两个栈的指针,我们还需要判断是存储进表1还是表2

#define MaxSize 100
typedef struct{
    int elem[MaxSiz e];
    int leftTop;
    int rightTop;
}SeqStack;

int InitStack(SeqStack *s){
	s = (SeqStack*)malloc(sizeof(SeqStack));
    if(s == NULL){
        printf("空间创建失败");
        return 0;
    }
    else{
        s->LeftTop = -1;
        s->rightTop = MaxSize;
        return 1;
    }
}
//入栈函数
int PushStack(SeqStack *s,int judge,int x){
    //judge是判断存入表1还是表2
    if(s->leftTop + 1==s->rightTop){
        printf("栈已满");
        return 0;
    }
    if(judge ==0){
        s->leftTop++;
        s->[leftTop] = x;
        return 1;
    }
    else if(judge ==1){
        s->rightTop--;
        s->[rightTop] = x;
        return 1;
    }
    else{
        printf("参数错误");
        return 0;
    }
}
//出栈函数
int PopStack(SeqStack *s,int judge , int *x){
    //判断是否栈空
        if(judge == 0){
            if(s->leftTop == -1){
                printf("栈空,无可出栈数据");
                return 0;
    		}
            else{
                *x = s->elem[leftTop]; 
                s->leftTop--;
                return 1;
    		}
        }
    	
    
    	else if(judge == 1){
            if(s->rightTop == -1){
                printf("栈空,无可出栈数据");
                return 0;
    		}
            else{
            	*x = s->elem[rightTop]; 
        		s->rightTop++;
                return 1;
    		}
        }
    
    else{
        printf("参数错误");
        return 0;
    }
    	
  
}

关于上面的x,只是用来存储删除的数据,可有可无,但习惯性的保存删除的数据,便于检查,也是一种代码规范


链栈

链栈就是通过链表实现存储的栈,整体的实现与顺序栈基本一致,我们就直接实现链栈的共享空间代码

//为了方便存放链表指针,我们把指针放在一个指针数组中
#define MaxSize 100
StackNode *top[MaxSize];
typedef struct StackNode{
 	int data;
    StackNode *next;
}StackNode;

//入栈操作
//采用头插法
int PushStack(StackNode *top[i] , int x){
    StackNode *p;
    p = (StackNode*)malloc(sizeof(StackNode));
    if(p == NULL){
        printf("分配内存失败");
        return 0;
    }
    p->next = top[i]->next;
    top[i]->next = p;
    return 1;
    
}

//出栈操作
int PopStack(StackNode *top[i] , int *x){
    StackNOde *p;
    if(top[i]->next == NULL){
        printf("空栈,无可删除数据");
        return 0;
    }
    else{
        p = top[i]->next;
        top[i]->next = p-next;
        x = p->data;
        free(p);
        return 1;
    }
    
}
    

这就是栈的基本操作了,是不是觉得对栈有一定的了解了呢,学完了基本的知识点,下一步就让我们去找实例去实践一下吧。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值