堆棧的三種實現方式

  傳統的堆棧操做只有 入棧push 和 出棧pop 兩種,沒有單獨的訪問棧頂元素的操做,訪問棧頂元素的惟一方式就是出棧(pop會把堆棧頂部的值移出堆棧並返回這個值)。這樣的pop存在反作用。node

  因此,咱們在這裏實現提供push、pop、top三種基本操做的堆棧。數組

實現堆棧這一抽象數據類型(ADT),即要實現:入棧(push)、出棧(pop)、訪問棧頂元素(top)的操做,另外加上兩個判斷 棧滿、棧空與否的函數。函數

一般,咱們能夠使用 靜態數組動態數組動態鏈表 這三種方式來實現堆棧。測試

首先,在stack.h文件中聲明 操做函數 以及 定義 堆棧的存儲類型。這個文件,通用於下面的三種實現方式,且在修改堆棧存儲類型時,只需簡單修改此文件便可。spa

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);

1、靜態數組方式實現堆棧code

stack1.c:  此種方法實現的堆棧,要修改堆棧長度只能修改該源文件中的STACK_SIZE值,並從新編譯纔可。blog

#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;
}

2、動態數組方式實現堆棧內存

stack2.c:  此種方法實現的堆棧,堆棧的長度在調用建立堆棧函數時,以函數參數的形式給出。element

#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;
}

3、動態鏈表方式實現堆棧

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;
}
相關文章
相關標籤/搜索