堆栈的三种实现方式
Posted Carrie_0173
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了堆栈的三种实现方式相关的知识,希望对你有一定的参考价值。
传统的堆栈操作只有 入栈push 和 出栈pop 两种,没有单独的访问栈顶元素的操作,访问栈顶元素的唯一方式就是出栈(pop会把堆栈顶部的值移出堆栈并返回这个值)。这样的pop存在副作用。
所以,我们在这里实现提供push、pop、top三种基本操作的堆栈。
实现堆栈这一抽象数据类型(ADT),即要实现:入栈(push)、出栈(pop)、访问栈顶元素(top)的操作,另外加上两个判断 栈满、栈空与否的函数。
通常,我们可以使用 静态数组、动态数组、动态链表 这三种方式来实现堆栈。
首先,在stack.h文件中声明 操作函数 以及 定义 堆栈的存储类型。这个文件,通用于下面的三种实现方式,且在修改堆栈存储类型时,只需简单修改此文件即可。
stack.h:
#define STACK_TYPE int //堆栈存储的值的类型 //入栈 void push(STACK_TYPE value); //出栈 void pop(void); //访问栈顶元素 STACK_TYPE top(void); //判断是否栈空 int is_empty(void); //判断是否栈满 int is_full(void);
一、静态数组方式实现堆栈
stack1.c: 此种方法实现的堆栈,要修改堆栈长度只能修改该源文件中的STACK_SIZE值,并重新编译才可。
#include "stack.h" #include <assert.h> //包含了 assert宏 #define STACK_SIZE 100 //堆栈中所存元素的最大数量 static STACK_TYPE stack[STACK_SIZE];//堆栈数组 static top_element = -1; //栈顶元素标识 //定义为static 使其只能在声明它们的源文件中被访问 //入栈push void push(STACK_TYPE value){ //栈满则不能再入栈,首先要判断是否栈满 assert(!is_full()); //assert宏,对表达式参数测试,若值为假,则打印错误信息并终止程序 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_full int is_full(void){ return top_element == STACK_SIZE-1; } //判断是否栈空is_empty int is_empty(void){ return top_element == -1; }
二、动态数组方式实现堆栈
stack2.c: 此种方法实现的堆栈,堆栈的长度在调用创建堆栈函数时,以函数参数的形式给出。
#include "stack.h" #include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <assert.h> static STACK_TYPE *stack;//堆栈指针 static size_t static_size; //保存堆栈可容纳元素个数的变量 stack_size 存储于全局存储区BSS段,将被初始化为0 static int top_element = -1;//栈顶元素标识 //创建堆栈的函数create_stack void create_stack(size_t size){ assert(stack_size == 0); //若stack_size!=0则说明堆栈已经创建 stack_size = size; //size为堆栈可容纳元素的个数 stack = malloc(stack_size * sizeof(STACK_TYPE)); assert(stack != NULL);//检验堆栈是否成功创建 } //销毁堆栈destroy_stack 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_full int is_full(void){ assert(stack_size > 0); return top_element == stack_size-1; } //is_empty int is_empty(void){ assert(stack_size > 0); return top_element == -1; }
三、动态链表方式实现堆栈
stack3.c: 此种实现方式,不需要单独提前创建堆栈,但要注意堆栈的销毁,以避免内存泄露。
#include "stack.h" #include <stdio.h> #include <stdlib.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; //用于清空堆栈的函数,防止内存泄露 void destroy_stack(void){ while(!is_empty()) pop(); } //push void push(STACK_TYPE value){ StackNode *new_node; new_node = malloc(sizeof(StackNode)); new_node->value = value; new_node->next = stack; stack = new_node; } //pop void pop(void){ StackNode *delete_node; assert(!is_empty()); delete_node = stack; stack = stack->next; free(delete_node); } //top Stack_TYPE top(void){ assert(!is_empty()); return stack->value; } //is_full int is_full(void){ return FALSEE; //堆栈长度除受内影响外,没有长度限制 } //is_empty int is_empty(void){ return stack == NULL; }
以上是关于堆栈的三种实现方式的主要内容,如果未能解决你的问题,请参考以下文章