首页 > 其他分享 >数据结构-栈

数据结构-栈

时间:2023-11-03 16:04:31浏览次数:23  
标签:struct DataType top 栈顶 stk 数据结构 Stack

一、概念

1、栈的定义

栈是仅限在表尾进行插入和删除的线性表。

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

2、栈顶

栈是一个线性表,我们把允许插入删除的一端称为栈顶

数据结构-栈_入栈

3、栈底

栈顶相对,另一端称为栈底

数据结构-栈_入栈_02

二、接口

1、可写接口

(1)数据入栈

栈的插入操作,叫做入栈,也可称为进栈、压栈。

数据结构-栈_数据结构_03

代表了两次入栈

(2)数据出栈

栈的删除操作,叫做出栈,也可以叫做弹栈

数据结构-栈_出栈_04

代表出了一次栈

(3)清空栈

一直出栈,直到栈为空

2、只读接口

(1)获取栈顶数据

对于一个栈来说只能获取栈顶数据,一般不支持获取其它数据

(2)获取栈元素个数

栈元素个数一般用一个额外变量存储,入栈时加一,出栈时减一

(3)栈的判空

当栈元素个数为零时,就是一个空栈,空栈不允许出栈操作

三、顺序表实现

1.数据结构定义

#define DataType int        // (1)定义为整型

#define maxn 100005         // (2)代表栈的最大元素个数


struct Stack {              // (3)结构体

    DataType data[maxn];    // (4)栈元素存储方式-数组

    int top;                // (5)栈顶指针

};

2.入栈

void StackPushStack(struct Stack *stk, DataType dt) { // (1)stk指向栈对象的指针

    stk->data[ stk->top ] = dt;                       // (2)将入栈的元素放入栈中

    stk->top = stk->top + 1;                          // (3)栈顶指针上移

}

可将代码简洁写为:

void StackPushStack(struct Stack *stk, DataType dt) {

    stk->data[ stk->top++ ] = dt;                    

}

3、出栈

void StackPopStack(struct Stack* stk) {

    --stk->top;

}

直接将栈顶元素减一下移即可

4、清空栈

对于数组来说,我们将栈顶指针直接置为栈底,也就是数组下标为0即可,下次入栈的时候会将之前的内存重复使用

void StackClear(struct Stack* stk) {

    stk->top = 0;

}

5、只读接口

DataType StackGetTop(struct Stack* stk) {

    return stk->data[ stk->top - 1 ];      // (1)获取栈顶元素
}

int StackGetSize(struct Stack* stk) {

    return stk->top;                       // (2)获取栈元素个数
}

bool StackIsEmpty(struct Stack* stk) {

    return !StackGetSize(stk);             // (3)判断栈是否为空
}

6、栈的顺序表实现源码

#define DataType int

#define bool int

#define maxn 100010


struct Stack {

    DataType data[maxn];

    int top;

};


void StackClear(struct Stack* stk) {

    stk->top = 0;

}

void StackPushStack(struct Stack *stk, DataType dt) {

    stk->data[ stk->top++ ] = dt;

}

void StackPopStack(struct Stack* stk) {

    --stk->top;

}

DataType StackGetTop(struct Stack* stk) {

    return stk->data[ stk->top - 1 ];

}

int StackGetSize(struct Stack* stk) {

    return stk->top;

}

bool StackIsEmpty(struct Stack* stk) {

    return !StackGetSize(stk);

}

四、栈的链表实现

1.、数据结构定义

typedef int DataType;             // (1)栈结点的数据域

struct StackNode;                 // (2)链表结点声明

struct StackNode {                // (3)data为数据域,*next指针域

    DataType data;

    struct StackNode *next;

};

struct Stack {                    

    struct StackNode *top;        // (4)栈顶指针

    int size;                     // (5)栈的元素个数,也就是链表的长度

};

2、入栈

类似头插法

void StackPushStack(struct Stack *stk, DataType dt) {
	 // (1)创建一个结点
    struct StackNode *insertNode = (struct StackNode *) malloc( sizeof(struct StackNode) );
	
    insertNode->next = stk->top;     // (2)当前结点指向栈顶结点

    insertNode->data = dt;           // (3)赋值

    stk->top = insertNode;           // (4)栈顶指针指向新创建的结点

   	stk->size++;                    // (5)栈元素个数加一

}

3、出栈

出栈过程就是删除这个链表的头结点

void StackPopStack(struct Stack* stk) {

    struct StackNode *temp = stk->top;  // (1)temp指向栈顶元素

    stk->top = temp->next;              // (2)栈顶指针执行它的下一个结点

    free(temp);                         // (3)将temp对应的结点释放

    stk->size--;                        // (4)栈元素个数减一    

}

4、清空栈

void StackClear(struct Stack* stk) {

    while(!StackIsEmpty(stk)) {       // (1)栈不为空

        StackPopStack(stk);           // (2)执行出栈操作

    }

    stk->top = NULL;                  // (3)将栈指针置NULL

}

5、只读接口

DataType StackGetTop(struct Stack* stk) {

    return stk->top->data;                 // (1)获取栈顶元素

}

int StackGetSize(struct Stack* stk) {

    return stk->size;                      // (2)栈元素个数

}


int StackIsEmpty(struct Stack* stk) {

    return !StackGetSize(stk);  //判空

}

6、栈的链表实现源码

typedef int DataType;


struct StackNode;

  
struct StackNode {

    DataType data;

    struct StackNode *next;

};


struct Stack {

    struct StackNode *top;

    int size;

};


void StackPushStack(struct Stack *stk, DataType dt) {

    struct StackNode *insertNode = (struct StackNode *) malloc( sizeof(struct StackNode) );

    insertNode->next = stk->top;

    insertNode->data = dt;

    stk->top = insertNode;

    stk->size++;

}

void StackPopStack(struct Stack* stk) {

    struct StackNode *temp = stk->top;

    stk->top = temp->next;

    stk->size--;  
    free(temp);

}


DataType StackGetTop(struct Stack* stk) {

    return stk->top->data;

}

int StackGetSize(struct Stack* stk) {

    return stk->size;

}


int StackIsEmpty(struct Stack* stk) {

    return !StackGetSize(stk);

}


void StackClear(struct Stack* stk) {

    while(!StackIsEmpty(stk)) {

        StackPopStack(stk);

    }

    stk->top = NULL;  
    stk->size = 0;

}

五、两种实现的优缺点

1、顺序表实现

入栈和出栈的常数时间复杂度低,清空栈时间复杂度是O(1)

不足之处是需要预习申请好空间,而且当空间不够时需要申请空间

2、链表实现

入栈和出栈的常数时间复杂度略高,清空栈的时间复杂度为O(n)

好处是不用预先分配空间,可以一直入栈。




标签:struct,DataType,top,栈顶,stk,数据结构,Stack
From: https://blog.51cto.com/u_15858858/8172083

相关文章

  • 【数据结构】第一章——绪论(1)
    数据结构的基本概念大家好,今天开始,我将开始从原先的专心学习C语言调整到边学习C语言,边学习数据结构的相关内容。当然,在学习的过程中我也会将各个知识点通过博客记录下来并将自己对知识点的理解分享给大家。本章内容是数据结构的概述,我们可以通过对本章内容的学习,初步了解数据结构的......
  • 图的数据结构及基础算法
    图(Graph)这个数据结构在平时开发中遇到的比较少,但我认为它是十分重要的,因为从真实的世界中来看,很多东西都可以抽象为图的表示,比如人际关系,地理位置,天马行空的东西都可以抽象为图,所以它比链表等基础数据结构高级一点点,也比较复杂,属于非线性结构。数学中有一个图论的分支也是与其有......
  • 查找附近店铺(Redis GEO数据结构实现)
    附近店铺(RedisGEO数据结构实现)GEO数据结构GEO就是Geolocation的简写形式,代表地理坐标。Redis在3.2版本中加入了对GEO的支持,允许存储地理坐标信息,帮助我们根据经纬度来检索数据。常见的命令有:GEOADD:添加一个地理空间信息,包含:经度(longitude)、纬度(latitude)、值(member)GEO......
  • 数据结构笔记
    数据结构刷题笔记Points线段树显然先对\(x\)离散用线段树维护区间最大值,查询在线段树上二分出最小的\(x\)用set维护每个\(x\)对应的\(y\),lower_bound即可......
  • 数据结构与算法 | 哈希表(Hash Table)
    哈希表(HashTable)在二分搜索中提到了在有序集合中查询某个特定元素的时候,通过折半的方式进行搜索是一种很高效的算法。那能否根据特征直接定位元素,而非折半去查找?哈希表(HashTable),也称为散列表,就是一种数据结构,用于实现键-值对的映射关系。它通过将键映射到特定的值(哈希值)来实现......
  • sizeof与各数据结构内存占用计算
    一、sizeof1.sizeof介绍sizeof会计算参数的数据类型所占字节数。注意事项:如果是数组类型(非vector),则会返回整个数组所占字节数。sizeof是运算符,在编译期间确定,因此无法计算动态分配的内存大小,如new等。2.实现方式获取type使用getTypeInfoChars(type)来计算字节......
  • 数据结构-ST表
    ST表的使用范围:1.处理静态数组的极值问题2.尾部增减数组的极值问题ST表的原理:1.预处理:ST表的中心思想是动态规划,我们规定数组Max[i][j]储存的是数组中从第i个元素开始,总共2^j个数字的极(大)值,区间末尾位置为i+2^j-1。输入数组时,直接输入到Max[i][0]上。输入完成后,花费......
  • Oracle转为Mysql的数据结构差别
     Oracle的表空间相关函数TABLESPACE"SYSTEM"LOGGINGNOCOMPRESSPCTFREE10INITRANS1STORAGE(INITIAL65536NEXT1048576MINEXTENTS1MAXEXTENTS2147483645FREELISTS1FREELISTGROUPS1BUFFER_POOLDEFAULT)PARALLEL1NOCACHEDISABLE......
  • 数据结构——二分查找(1)
    ``点击查看代码importjava.util.Scanner;publicclassMain{publicstaticint[]a=newint[10];publicstaticvoidmain(String[]args){Scanners=newScanner(System.in);intn=s.nextInt();intb......
  • C++数据结构
    C++数据结构C/C++数组允许定义可存储相同类型数据项的变量,但是结构体是C++中另外一种用户自定义的可用的数据类型,它允许存储不同类型的数据项。结构用于表示一条记录,假设要跟踪图书馆书本的动态,可能需要跟踪每本书的下列属性:TitleAuthorSubjectBookID定义结构体......