堆栈有几种实现方式?
堆栈有3种实现方式,实现方式为:1、静态数组堆栈,要求结构的长度固定,而且长度在编译时候就得确定;2、动态数组堆栈,长度可以在运行时候才确定以及可以更改原来数组的长度;3、链式结构堆栈,无长度上线,需要的时候再申请分配内存空间。
堆栈有3种实现方式,实现方式为:
一、静态数组堆栈
在静态数组堆栈中,STACK_SIZE
表示堆栈所能存储的元素的最大值,用top_element
作为数组下标来表示堆栈里面的元素,当top_element == -1
的时候表示堆栈为空;当top_element == STACK_SIZE - 1
的时候表示堆栈为满。push的时候top_element
加1,top_element == 0
时表示第一个堆栈元素;pop的时候top_element
减1。
a_stack.c 源代码如下:
[cpp] view plain copy /* ** ** 静态数组实现堆栈程序 a_stack.c ,数组长度由#define确定 */ #include"stack.h" #include<assert.h> #include<stdio.h> #define STACK_SIZE 100 /* 堆栈最大容纳元素数量 */ /* ** 存储堆栈中的数组和一个指向堆栈顶部元素的指针 */ static STACK_TYPE stack[STACK_SIZE]; static int top_element = -1; /* push */ void push(STACK_TYPE value) { assert(!is_full()); /* 压入堆栈之前先判断是否堆栈已满*/ top_element += 1; stack[top_element] = value; } /* pop */ void pop(void) { assert(!is_empty()); /* 弹出堆栈之前先判断是否堆栈已空 */ top_element -= 1; } /* top */ STACK_TYPE top(void) { assert(!is_empty()); return stack[top_element]; } /* is_empty */ int is_empty(void) { return top_element == -1; } /* is_full */ int is_full(void) { return top_element == STACK_SIZE - 1; } /* ** 定义一个print函数,用来打印堆栈里面的元素。 */ void print(void) { int i; i = top_element; printf("打印出静态数组堆栈里面的值: "); if(i == -1) printf("这是个空堆栈\n"); while(i!= -1) printf("%d ",stack[i--]); printf("\n"); } int main(void) { print(); push(10); push(9); push(7); push(6); push(5); push(4); push(3); push(2); push(1); push(0); printf("push压入数值后:\n"); print(); printf("\n"); pop(); pop(); printf("经过pop弹出几个元素后的堆栈元素:\n"); print(); printf("\n"); printf("top()调用出来的值: %d\n",top()); return 1; }
结果如下图:
二、动态数组堆栈
头文件还是用stack.h
,改动的并不是很多,增加了stack_size
变量取代STACK_SIZE
来保存堆栈的长度,数组由一个指针来代替,在全局变量下缺省为0。
create_stack
函数首先检查堆栈是否已经创建,然后才分配所需数量的内存并检查分配是否成功。destroy_stack
函数首先检查堆栈是否存在,已经释放内存之后把长度和指针变量重新设置为零。is_empty
和 is_full
函数中添加了一条断言,防止任何堆栈函数在堆栈被创建之前就被调用。
d_stack.c
源代码如下:
[cpp] view plain copy /* ** 动态分配数组实现的堆栈程序 d_stack.c ** 堆栈的长度在创建堆栈的函数被调用时候给出,该函数必须在任何其他操作堆栈的函数被调用之前条用。 */ #include"stack.h" #include<stdio.h> #include<malloc.h> #include<assert.h> /* ** 用于存储堆栈元素的数组和指向堆栈顶部元素的指针 */ static STACK_TYPE *stack; static int stack_size; static int top_element = -1; /* create_stack */ void create_stack(size_t size) { assert(stack_size == 0); stack_size = size; stack = (STACK_TYPE *)malloc(stack_size * sizeof(STACK_TYPE)); if(stack == NULL) perror("malloc分配失败"); } /* destroy */ void destroy_stack(void) { assert(stack_size > 0); stack_size = 0; free(stack); stack = NULL; } /* push */ void push(STACK_TYPE value) { assert(!is_full()); top_element += 1; stack[top_element] = value; } /* pop */ void pop(void) { assert(!is_empty()); top_element -= 1; } /* top */ STACK_TYPE top(void) { assert(!is_empty()); return stack[top_element]; } /* is_empty */ int is_empty(void) { assert(stack_size > 0); return top_element == -1; } /* is_full */ int is_full(void) { assert(stack_size > 0); return top_element == stack_size - 1; } /* ** 定义一个print函数,用来打印堆栈里面的元素。 */ void print(void) { int i; i = top_element; printf("打印出动态数组堆栈里面的值: "); if(i == -1) printf("这是个空堆栈\n"); while(i!= -1) printf("%d ",stack[i--]); printf("\n"); } int main(void) { create_stack(50); print(); push(10); push(9); push(7); push(6); push(5); push(4); push(3); push(2); push(1); push(0); printf("push压入数值后:\n"); print(); printf("\n"); pop(); pop(); printf("经过pop弹出几个元素后的堆栈元素:\n"); print(); printf("\n"); printf("top()调用出来的值: %d\n",top()); destroy_stack(); return 1; }
结果如下图:
三、链式堆栈
由于只有堆栈顶部元素才可以被访问,因此适用单链表可以很好实现链式堆栈,而且无长度限制。把一个元素压入堆栈是通过在链表头部添加一个元素实现。弹出一个元素是通过删除链表头部第一个元素实现。由于没有长度限制,故不需要create_stack
函数,需要destroy_stack
进行释放内存以避免内存泄漏。
头文件stack.h
不变,l_stack.c
源代码如下:
[cpp] view plain copy /* ** 单链表实现堆栈,没有长度限制 */ #include"stack.h" #include<stdio.h> #include<malloc.h> #include<assert.h> #define FALSE 0 /* ** 定义一个结构以存储堆栈元素。 */ typedef struct STACK_NODE { STACK_TYPE value; struct STACK_NODE *next; } StackNode; /* 指向堆栈中第一个节点的指针 */ static StackNode *stack; /* create_stack */ void create_stack(size_t size) {} /* destroy_stack */ void destroy_stack(void) { while(!is_empty()) pop(); /* 逐个弹出元素,逐个释放节点内存 */ } /* push */ void push(STACK_TYPE value) { StackNode *new_node; new_node = (StackNode *)malloc(sizeof(StackNode)); if(new_node == NULL) perror("malloc fail"); new_node->value = value; new_node->next = stack; /* 新元素插入链表头部 */ stack = new_node; /* stack 重新指向链表头部 */ } /* pop */ void pop(void) { StackNode *first_node; assert(!is_empty()); first_node = stack; stack = first_node->next; free(first_node); } /* top */ STACK_TYPE top(void) { assert(!is_empty()); return stack->value; } /* is_empty */ int is_empty(void) { return stack == NULL; } /* is_full */ int is_full(void) { return FALSE; } /* ** 定义一个print函数,用来打印堆栈里面的元素。 */ void print(void) { StackNode *p_node; p_node = stack; printf("打印出链式堆栈里面的值: "); if(p_node == NULL) printf("堆栈为空\n"); while(p_node != NULL) { printf("%d ", p_node->value); p_node = p_node->next; } printf("\n"); } int main(void) { print(); push(10); push(9); push(7); push(6); push(5); push(4); push(3); push(2); push(1); push(0); printf("push压入数值后:\n"); print(); printf("\n"); pop(); pop(); printf("经过pop弹出几个元素后的堆栈元素:\n"); print(); printf("\n"); printf("top()调用出来的值: %d\n",top()); destroy_stack(); return 1; }
结果如下图:
推荐教程:《java视频教程》
以上是堆栈有几种实现方式?的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

MyBatis中实现批量删除语句的几种方式,需要具体代码示例近年来,由于数据量的不断增加,批量操作成为了数据库操作的一个重要环节之一。在实际开发中,我们经常需要批量删除数据库中的记录。本文将重点介绍在MyBatis中实现批量删除语句的几种方式,并提供相应的代码示例。使用foreach标签实现批量删除MyBatis提供了foreach标签,可以方便地遍历一个集

待机是iOS17更新中的一项新功能,它提供了一种新的增强方式,可以在手机快速闲置时访问信息。通过StandBy,您可以方便地查看时间、查看即将发生的事件、浏览日历、获取您所在位置的天气更新等等。激活后,iPhone在充电时设置为横向时会直观地进入待机模式。此功能非常适合床头柜等无线充电点,或者在日常任务中离开iPhone充电时。它允许您轻扫待机中显示的各种小部件,以访问来自各种应用程序的不同信息集。但是,您可能希望根据您的偏好和您经常需要的信息修改这些小部件,甚至删除一些小部件。因此,让我们深入

待机是iOS17中一种新的可自定义锁屏模式,可在iPhone充电并侧卧时激活。可以将其视为iPhone的一种智能显示屏,例如,当您的设备在厨房,书桌或床头柜上充电时,可以快速访问可以远处查看的不同可浏览信息屏幕。自定义备用构件待机由三个屏幕组成,可以通过在iPhone显示屏上水平滑动来访问。第一个屏幕是交互式小部件所在的位置,而向左滑动会显示第二个和第三个屏幕,分别显示照片图库中的照片和大时钟显示。小部件屏幕由两个并排显示的交互式小部件堆栈组成,您可以独立地上下滑动。这些堆栈就像主屏幕小部件堆栈

PHP中的OAuth2鉴权方法及实现方式随着互联网的发展,越来越多的应用程序需要与第三方平台进行交互。为了保护用户的隐私和安全,许多第三方平台使用OAuth2协议来实现用户鉴权。在本文中,我们将介绍PHP中的OAuth2鉴权方法及实现方式,并附上相应的代码示例。OAuth2是一种授权框架,它允许用户授权第三方应用程序访问其在另一个服务提供商上的资源,而无需提

Golang继承方法的基本原理与实现方式在Golang中,继承是面向对象编程的重要特性之一。通过继承,我们可以使用父类的属性和方法,从而实现代码的复用和扩展性。本文将介绍Golang继承方法的基本原理和实现方式,并提供具体的代码示例。继承方法的基本原理在Golang中,继承是通过嵌入结构体的方式实现的。当一个结构体嵌入另一个结构体时,被嵌入的结构体就拥有了嵌

在过去的几十年中,计算机编程已经经历了许多变化和进化。其中一个最新的编程范式被称为响应式编程(reactiveprogramming),它在高质量、高并发的Web应用程序开发中变得更加流行。PHP是一种流行的Web编程语言,提供了丰富的库和框架来支持响应式编程。在本文中,我们将介绍PHP7.0中响应式编程的实现方式。什么是响应式编程?在开始讨论PHP7.0

随着互联网的普及和高速网络的加速,直播已经成为了一种非常流行的互联网应用。直播能够为用户提供实时的视频和音频流,并能够进行互动和交流,因此在各种社交平台和在线教育中广泛应用。而在直播应用中,PHP也是一种非常重要的编程语言之一,很多网站和应用都使用PHP来实现直播功能。本文将介绍PHP实现直播功能的三种方式。一、使用RTMP协议RTMP(RealTime

解读Struts2框架的原理及实现方式引言:Struts2作为一种流行的MVC(Model-View-Controller)框架,被广泛应用于JavaWeb开发中。它提供了一种将Web层与业务逻辑层分离的方式,并且具有灵活性和可扩展性。本文将介绍Struts2框架的基本原理和实现方式,同时提供一些具体的代码示例来帮助读者更好地理解该框架。一、框架原理:St
