数据结构之栈_java数据结构与算法

数据结构之栈_java数据结构与算法一.什么是栈二.几道小题开胃三.栈的代码实现1.创建项目2.创建栈结构3.栈的初始化4.入栈操作5.出栈操作6.返回栈顶元素7.求栈元素个数8.判断栈是否为空9.栈的销毁四.总结:五.原码链接…_先进先出栈

前言:栈是一种线性表。我们要先了解顺序表和链表才更好实现栈!大家可以看看我的前几篇文章。

静态顺序表 动态顺序表
单链表 双向链表

目录

一.什么是栈

二.几道小题开胃

三.栈的代码实现

1.创建项目

2.创建栈结构

3.栈的初始化

4.入栈操作

5.出栈操作

6.返回栈顶元素

7.求栈元素个数

8.判断栈是否为空

9.栈的销毁

四.总结:

五.原码链接


一.什么是栈

栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作进行数据插入和删除操作的一端称为栈顶,另一端称为栈底栈中的数据元素遵守:后进先出LIFOLast In First Out)的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈。出数据也在栈顶。
数据结构之栈_java数据结构与算法

二.几道小题开胃

题目1:

数据结构之栈_java数据结构与算法

栈结构特点:先进后出   

入栈顺序为:1 2 3 4 5 A B C D E

所以出栈顺序为:E D C B A 5 4 3 2 1  选择B

题目2:

数据结构之栈_java数据结构与算法

       栈:先进后出             题中:进栈过程中可以出栈

A:1进栈,再出栈,然后2,3,4进栈,4,3,2的顺序出栈

B:1,2进栈,2出栈,3进栈,3出栈,4进栈,4出栈,1出栈

C:1,2,3进栈,3出栈,因为先进后出,只能先出2再出1。  C错!

D:1,2,3进栈,3出栈,4进栈,4出栈,2出栈,1出栈。


三.栈的代码实现

1.创建项目

思考:用什么结构实现栈比较好?

1.若用数组实现:相当于顺序表的尾插尾删,用尾做了栈顶,非常合适!

        缺陷:空间不够需要增容

数据结构之栈_java数据结构与算法


 2.若用单链表实现:

1. 如果用尾做栈顶,那么用双向链表更好。 

2.如果要用单链表实现,那么就用头做栈顶更好,这入栈和出栈效率都是O(1)

数据结构之栈_java数据结构与算法

 综上,使用数组更好!因为静态顺序表不能增容,所以我们使用动态顺序表!

程序 实现的内容
Stack.h 变量的定义,函数的声明,头文件的包含。
Stack.c 函数的定义
test.c 测试函数功能

2.创建栈结构

为了方便后序更改类型,我们经常使用typedef定义。

typedef int STDataType; typedef struct Stack { STDataType* arr; //指向动态开辟的数组 int top; //标志栈顶 int capacity;//容量 }ST;

3.栈的初始化

注意:最初我们要为动态数组开辟空间。

关于top:若我们最初定义top为0,top指向的是栈顶后一个元素。因为放元素到arr[top]位置后,top++变为1若我们定义top为-1,top指向的就算栈顶,top先++变为0,然后放元素到arr[top]位置。

//初始化 void StackInit(ST* ps) { assert(ps); //最初先为数组开辟空间 STDataType* tmp = (STDataType*)malloc(sizeof(STDataType) * 4); //先给4个空间 if (tmp == NULL) { printf("malloc fail\n"); exit(-1); } else { ps->arr = tmp; ps->top = 0; //top初始化为0,top指向的是栈顶的下一个位置 // top =0,插入到arr[0] top++->top变为1 所以top在栈顶后 //若top初始化为-1,top指向的就是栈顶元素 //先top++再插入->top=0,插入位置arr[0] 所以二者在同一位置 ps->capacity = 4; //给了4个空间,容量为4 } }

4.入栈操作

1.插入数据要先判断数据满了没有->若满了,则要扩容,扩两倍

2.元素入栈:把元素放到top指向位置,然后top++。

在这里插入图片描述

//入栈 //注意入栈要先考虑容量是否充足 void StackPush(ST* ps,STDataType x) { assert(ps); //容量满了 if (ps->top == ps->capacity) { STDataType* tmp = (STDataType *)realloc(ps->arr, sizeof(STDataType) * 2 * ps->capacity); if (tmp == NULL) { printf("recalloc fail\n"); exit(-1); } else { ps->arr = tmp; ps->capacity *= 2; //扩容扩两倍 } } //入栈操作 ps->arr[ps->top] = x; ps->top++; } 

5.出栈操作

注意:要保证栈内还有元素,防止空栈!

出栈:top–,  top原来指向的元素还在,但是我们已经访问不了了!

在这里插入图片描述

//出栈 void StackPop(ST* ps) { assert(ps); assert(ps->top > 0);//要保证栈内有元素 最初定义top为0,top=1才有第一个元素 ps->top--; }

6.返回栈顶元素

注意:我们也要保证栈内有元素。

因为我们最初定义top为0,top指向栈顶后的元素,所以返回的是top-1位置的元素才是栈顶元素

 数据结构之栈_java数据结构与算法

//返回栈顶元素 STDataType StackType(ST* ps) { assert(ps); assert(ps->top > 0);//要保证栈内有元素 return ps->arr[ps->top - 1]; //最初定义top为0,top在栈顶后 }

7.求栈元素个数

top的值就是元素个数

//求栈元素个数 int StackSize(ST* ps) { assert(ps); return ps->top; }

8.判断栈是否为空

最初定义top为0,表示栈内没有元素!若top仍未0,说明栈为空!

//判断栈是否为空 bool StackEmpty(ST* ps) { assert(ps); return ps->top == 0; //最初定义top为0 若top仍未0,说明栈为空 }

9.栈的销毁

因为数组是动态开辟的,所以我们要释放掉,并把指针置空!防止内存泄漏

//销毁 void StackDestory(ST* ps) { assert(ps); free(ps->arr); ps->arr = NULL; ps->capacity = ps->top = 0; }

四.总结:

 当我们打印数据时,不能遍历打印数据。因为这样就不满足栈:先进先出的特点。

 //由于栈是先进后出,所以不可以通过遍历来打印 //只能一步步的返回栈顶元素,再出栈,再返回栈顶元素,以此循环,知道栈为空 while (!StackEmpty(&p)) //当栈为空,StackEmpty为真 !StackEmpty为假,不进入循环 { //取栈顶元素 printf("%d ", StackType(&p)); //出栈 StackPop(&p); }

 先取栈顶元素,然后栈顶元素出栈


五.原码链接

数据结构之栈-代码

今天的文章
数据结构之栈_java数据结构与算法分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/60719.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注