傳統的堆棧操做只有 入棧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; }