zoukankan      html  css  js  c++  java
  • 堆栈的三种实现方式

      传统的堆栈操作只有 入栈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;
    }
  • 相关阅读:
    PreparedStatement/Statement处理insert update等操作时乱码,以及URL
    MySQL unique 注意
    web乱码解决了
    实用工具及Chrome插件及实用网站(持续更新中...)
    前端常用算法集合,持续更新...
    各种问题汇总解决方法,持续更新中...
    node实现自动化图片切割压缩, 部署页面
    移动端图片缩放插件Pinchzoom.js
    提示框简单封装
    模拟滚动条
  • 原文地址:https://www.cnblogs.com/Carrie-0173/p/6365105.html
Copyright © 2011-2022 走看看