数据结构——栈

本文介绍了数据结构中栈的相关知识。栈是“先进后出”的数据结构,有创建、压栈、出栈等操作,分为静态栈和动态栈。还说明了进栈出栈的变换形式,对比了链式栈与静态栈的区别,最后阐述了栈能简化程序设计问题的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

栈的定义

栈是一种“先进后出”的数据结构,只能从一个位置进,从一个位置出。

栈的操作

栈具有创建栈,压栈、出栈,获取栈顶元素等操作方式。

栈的分类

栈主要分为两类:静态栈(顺势栈)动态栈(链式栈)

静态栈:静态栈主要就是运用数组,类似于一个连续内存的数组,我们只能操作栈顶元素。

动态栈:动态栈的核心是链表,我们也只能操作栈顶元素。

进栈出栈的变换形式

对于栈的元素,进行出栈操作时,最后进栈的元素,不一定只能最后出栈。栈对线性表的插入和删除的位置进行了限制,并没有对元素进出的时间进行限制,也就是说,并不是所有元素都进栈的情况下,事先进去的元素也可以出栈,只要保证栈顶元素出栈就可以了。

       例如现在有1、2、3三个元素依次进栈,出栈次序有321,123,132,213,231。这几种出栈次序,而312这种出栈次序是肯定不会有的,因为进栈次序是规定了的

 

静态栈

#include <stdio.h>
#include <stdlib.h>
#define  P 5             //定义最大栈容量
typedef struct Stack     //定义栈
{
    int data[P];         //栈中的数据
    int top;             //栈顶
}stack;

stack Init()//初始化栈
{
    stack s;
    s.top = -1;
    return s;
}

int Push(stack &s,int n)          //进栈操作
{

    if(s.top == P-1)              //进栈的时候必须判断是否栈满 
	{
        printf("stack full\n");
	}
    s.top++;

    s.data[s.top] = n;

	if(s.top == P-1)              //进栈结束的时候判断是否栈满 
	{
		return 0;
	}
	return 1;
}

int Come(stack &s)                    //出栈操作
{
	int n;    
    if(s.top == -1)                   //出栈的时候必须判断是否栈空 
	{
        printf("stack empty\n");
		return 0;
	}
    n = s.data[s.top];
    s.top--;

    return n;

}

int main()
{
    int n,i=1;
    stack  s;       //定义结构体变量s
    s = Init();     //初始化栈
    printf("请输入进栈的元素:\n"); 
    while(i)
    {
	scanf_s("%d",&n);
	i = Push(s,n);	
    }
    printf("出栈的结果:"); 
    while(s.top != -1)
    {
        printf("%d ",Come(s));
    }
    printf("\n");
	system ("pause");
    return 0;
} 

 动态栈

动态栈的做法与链表的头插法很类似,都是先进入的元素后出来。、

动态栈的定义

typedef struct Node         //定义一个链栈结点结构体
{
    int date;               //结点数据
    struct Node *next;      //结点指针
}*node;                     //结点名

typedef struct Stack        //定义链式栈结构体
{
    node top;               //栈顶指针
    int count;              //记录栈结点数量
}stack;                     //栈名

动态栈的入栈操作

void push(stack *S)
{
    int m,i;
    int n;                      //入栈元素
    printf("请输入你需要入栈数据的个数:  ");
    scanf_s("%d",&m);
    for(i=0;i<m;i++)
    {
	printf("你输入的第%d个数据为 :",i+1);
	scanf_s("%d",&n);       //输入数据
	node s = (node)malloc(sizeof(struct Node));//申请一个新结点
	s -> date = n;          //将数据付给date      
	s -> next = S->top;     //让新建结点的下一个结点等于现在的栈顶结点
	S -> top = s;           //让新结点成为新的栈顶结点
	S -> count ++;          //栈中结点数据加一	
    }
}

动态栈的出栈

void pop(stack *S)
{
    node s;                        //定义一个结点指针变量
    if(S->count == 0)              //判断栈是否为空
    {                      
		printf("栈空\n"); 
		exit(0);
    }  
    printf("出栈结果为:  ");             
    while(S->count != 0)
    {
	s = S->top;                //让新定义的结点指针指向当前栈顶
	printf("%d ",s->date);     //输出结点数据
	S->top=s->next;            //让栈顶指针指向栈顶结点的下一个结点
	free(s);                   //释放掉结点s
	S->count--;                //结点个数减一
    }
    printf("\n\n");
}

栈取栈顶元素

void Gettop(stack *S)
{
    if(S->count == 0)                //判断栈是否为空
    {                      
	printf("栈空\n"); 
	exit(0);
    }  
    printf("栈顶元素为:  ");   
    printf("%d ",S->top->date);      //输出结点数据
    printf("\n\n");
}

主程序

int main()
{
    int i;                  //用于选择的变量
    stack S;                //创建栈变量
    S.count = 0;            //初始化
    while(1)
    {
	printf("请选择下列操作\n");
	printf("1:进栈操作\n");
	printf("2:出栈操作\n");
	printf("3:取栈顶元素\n");
	printf("4:退出\n");
	scanf_s("%d",&i);
	switch(i)
        {
	case 1:push(&S); break;              //进栈操作
	case 2:pop(&S);  break;              //出栈操作
	case 3:Gettop(&S);break;             //取栈顶元素
	case 4:exit(0);                      //退出程序

	default:
	printf("输入错误,请重新输入!!!\n");
	break;
        }
    }
	printf("\n");
	system ("pause");
	return 0;
}

输出结果 

链式栈与静态栈最大的区别就是,链式栈不用确定栈的最大容量,不用担心容量不够的情况。

栈的作用

我们学习栈到底有什么作用呢?他和数组类似,那我们学习了数组又为何要学习栈。因为栈的引入简化了程序设计的问题,划分了不同关注层次使得思考范围缩小,更加聚焦于我们要解决的问题核心。反之,像数组等,要分散精力去考虑数组的下标增减等细节问题,反而掩盖了问题的本质

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值