首页 > 其他分享 >[数据结构] 栈 (C语言)

[数据结构] 栈 (C语言)

时间:2023-01-19 23:00:10浏览次数:50  
标签:LinkStack 出栈 入栈 top 元素 C语言 链栈 数据结构

栈的概念

栈(stack)是一种特殊的线性表存储结构,其一端可以进行插入和弹出的操作,而另一端是封死的。

可以把栈想象成是一个柱状的容器。就比如一个乒乓球筒,我们只能在筒的一段进行乒乓球的放入和取出。

栈顶和栈的两种操作

栈顶就是栈的开口端,每次都是在栈顶处插入元素和删除元素。
(1)入栈:将新元素存入栈中,并作为新的栈顶元素;
(2)出栈:将栈顶元素弹出,并将其下面的元素作为新的栈顶元素。

栈的特性

栈有着先进先出的特性。假如入栈元素依次是 1、2、3 ,且中途没有元素出栈,那么最后所有元素出栈的顺序是 3、2、1



顺序栈

顺序栈基本概念

顺序栈是用数组来实现栈的存储结构,一般会定义一个栈顶 top,初始情况下 top 值为-1,表示栈为空,此时栈中无任何元素。
每当有元素入栈,top+1 ; 有元素出栈, top-1

顺序栈的入栈操作

顺序栈入栈操作图解

初始情况下的栈

元素1入栈

元素2入栈

元素3入栈

顺序栈入栈操作代码

//元素入栈
void push(SqStack *s, Elemtype x){
    if(s->top == MAXSIZE - 1) return;  //栈满
    s->data[++s->top] = x;
}


顺序栈的出栈操作

顺序栈出栈操作图解

元素3出栈

元素2出栈

元素1出栈

顺序栈出栈操作代码

//元素出栈
void pop(SqStack *s, Elemtype *x){
    if(s->top == -1) return;  //栈空
    *x = s->data[s->top--];
}


顺序栈完整程序

源代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 1000

typedef int Elemtype;
typedef struct{

    Elemtype data[MAXSIZE];
    int top;                //栈顶指针

}SqStack;

//初始化栈
void Init_SqStack(SqStack *s){
    s->top = -1;
}

//判断栈是否为空
bool IsEmpty(SqStack *s){
    return s->top == -1;
}

//元素入栈
void push(SqStack *s, Elemtype x){
    if(s->top == MAXSIZE - 1) return;
    s->data[++s->top] = x;
}

//元素出栈
void pop(SqStack *s, Elemtype *x){
    if(s->top == -1) return;
    *x = s->data[s->top--];
}

//取栈顶元素
Elemtype top(SqStack *s){
    if(IsEmpty(s)){
	printf("栈为空\n");
	return -1;
    }
    return s->data[s->top];
}

int main(){
    SqStack mystack;
    Init_SqStack(&mystack);

    for(int i = 1; i <= 5; i++)
	push(&mystack, i);
    printf("当前栈顶元素为: %d\n", top(&mystack));

    int e;
    pop(&mystack, &e);
    printf("出栈元素为: %d\n", e);
    printf("当前栈顶元素为: %d\n", top(&mystack));

    printf("全部元素出栈:\n");
    while(!IsEmpty(&mystack)){
    	printf("%d ", top(&mystack));
    	pop(&mystack, &e);
    }
}

顺序栈运行测试



链栈

链栈基本概念

链栈是用链式存储结构实现的,在实现过程中,需要定义一个 top 指针保持指向当前栈顶。操作过程和链表有些相似。

链栈的入栈操作

链栈入栈操作图解

初始情况下的链栈

元素1入栈

元素2入栈

元素3入栈

链栈入栈操作代码

//入栈
void LinkStack_push(LinkStack *S, ElemType e){
    LinkStacknode *node;            
    node = (LinkStacknode *) malloc(sizeof(LinkStack));
    node->data = e;            
    node->next = S->top;       //新节点的next指向此时的top
    S->top = node;             //top指针指向新的节点

    S->length++;
}



链栈的出栈操作

链栈出栈操作图解

元素3出栈

元素2出栈

元素1出栈

链栈出栈操作代码

//出栈
void LinkStack_pop(LinkStack *S, ElemType *e){
    if(IsEmpty(S))               //栈空
        return;                  
    LinkStacknode *del = S->top; 
    *e = del->data;              
    S->top = del->next;          //top跳过出栈节点,指向出栈节点的下一节点

    S->length--;
    free(del);                   //释放内存
}


链栈完整程序

源代码

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

//定义数据类型
typedef int ElemType;

//链栈的节点结构
typedef struct LinkStacknode
{

    ElemType data;              //存数据
    struct LinkStacknode *next; //存下个节点的地址

} LinkStacknode;

//链栈的整体结构  
typedef struct {

    LinkStacknode *top;
    int length;
    
} LinkStack;


//初始化链栈
void Create_LinkStack(LinkStack *S){
    S->top = NULL;
    S->length = 0;
}

//判断栈为空
bool IsEmpty(LinkStack *S){
    return S->length == 0;
}

//入栈
void LinkStack_push(LinkStack *S, ElemType e){
    LinkStacknode *node;            
    node = (LinkStacknode *) malloc(sizeof(LinkStack));
    node->data = e;            
    node->next = S->top;       //新节点的next指向此时的top
    S->top = node;             //top指针指向新的节点

    S->length++;
}

//出栈
void LinkStack_pop(LinkStack *S, ElemType *e){
    if(IsEmpty(S))               //栈空
        return;                  
    LinkStacknode *del = S->top; 
    *e = del->data;              
    S->top = del->next;          //top跳过出栈节点,指向出栈节点的下一节点

    S->length--;
    free(del);                   //释放内存
}

//取栈顶
ElemType LinkStack_getTop(LinkStack *S){
    if(IsEmpty(S)){
        printf("栈为空\n");
        return -1;
    }
    return S->top->data;
}

int main(){
    LinkStack S;
    Create_LinkStack(&S);

    ElemType e;
    ElemType a[5] = {3,6,7,9,10};
    for(int i = 0; i < 5; i++)
        LinkStack_push(&S, a[i]);

    printf("栈顶元素:%d\n", LinkStack_getTop(&S));

    LinkStack_pop(&S, &e);
    printf("出栈元素:%d\n", e);   

    printf("全部元素出栈:\n");
    while(!IsEmpty(&S)){
        printf("%d ", LinkStack_getTop(&S));
        LinkStack_pop(&S, &e);
    }
    return 0;
}

链栈运行测试



标签:LinkStack,出栈,入栈,top,元素,C语言,链栈,数据结构
From: https://www.cnblogs.com/MAKISE004/p/17062088.html

相关文章

  • C语言概述
    一.C语言程序初识,先介绍一个简单的C语言程序:#include<stdio.h>intarr[100000];//声明一个较大的整型数组,尽量放在函数外部/*原因是:函数内部申请的局部变量空间,来自于......
  • C语言自加问题与整形提升
    提问:   在程序里,++a和+a在sizeof里,明显++a没有进行运算而+a进行运算并整形提升,这是为什么?解答: 这跟提升没有关系,这是运算优先级问题++a,运算优先级最高,所以是先进......
  • 如何使用C语言实现汉诺塔
    现有3个柱子A、B、C,有n个圆盘在A柱上,要实现n个圆盘要从A柱从大到小移动到C柱。思路:先将n-1个圆盘移动到B柱上,然后将最后一个圆盘移动到C柱上,最后将B柱上的n-1个圆盘移动到C......
  • c语言 打印数字金字塔
    提问: c语言。打印数字金字塔。for循环中为什么是j<i+1呢?以及如何判断这里的控制变量到底是与n有关还是与循环变量i有关呢?需要详细的解答 #include<stdio.h>voidpi......
  • c语言实现扫雷
    前言:上一篇博客我们写了三子棋小游戏,紧着这我们趁热打铁,继续巩固知识点,再来写一个更有意思的扫雷吧,想必扫雷大家都玩过,我就不做介绍了。概述:我们一样将代码分为三部分来写,主......
  • C语言运算符&优先级
    运算符优先级这一块即使你用了很久C语言,如果不刻意记忆,也是容易搞混的.C语言的运算符非常多,一共有50多种,可以分成若干类。算术运算符算术运算符专门用于算术......
  • C语言学院教学信息管理系统[2023-01-19]
    C语言学院教学信息管理系统[2023-01-19]30、某学院教学信息管理系统功能:1、每一条记录包括一位教师的职工号、姓名、职称、性别、3门主讲课程(课程名称、开课学期、课......
  • C语言核酸检测系统[2023-01-19]
    C语言核酸检测系统[2023-01-19]项目九:核酸检测系统1.教学内容实现一个简单的核酸检测系统,业务包括:将被检测人员的信息精准记录在系统中,并实时更据,实现精准监控并快速......
  • C语言中的整型数据类型(你真的了解吗)
    1.整型数据类型C语言里面的整数数据类型类型名称C语言中的关键字注释字符型char表示一个很小的整数短整型short表示一个不怎么大的整数整型int生活中一般的整数都可以表示......
  • 第一个C语言程序(从Hello World开始)
    程序员之间有一个约定俗成的习惯,我们在学习任何编程语言时,所写的第一个程序,就是在显示屏上打印一行字符​​“HelloWorld”​​。这个习惯出自哪里呢,首先回顾C语言的历史,就......