1什么是栈以及栈的特征
以后的数据结构中都会先放这样一张图(1):
图1
图中很清晰的说明 , 栈是属于线性表中的一种数据结构,只是操作的方式比较特殊一点,只允许在栈的一端进行插入,和删除的操作,而在插入的这一端上如果没有数据的话,就叫做空栈(Empty stack), 如果插入的数据>=初始设定的长度就叫做满栈(Full stack)如图(2),
栈里的数据是属于先进后出的,打个形象的比方就是说一个死胡同(栈)开进去了很多车子(栈里的数据),最里面的车子(最先入栈的数据a1)只有等外面的车子(a2...an)依次开出去,才轮到它(a1)开出去,不知道这样子小伙伴能否增加一些理解
图2
2栈的实现:
既然上面说到了 , 栈是线性表 , 那么,栈也就存在顺序存储和链式存储两种方式
首先实现顺序存储:
//Stack.h
#ifndef __STACK_H__ #define __STACK_H__ #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 10 //定义栈的最大存储空间 typedef void (*stack_op_t)(void *); //函数指针,指向打印栈元素的值的函数 typedef struct Stack{//定义一个栈 void *data;//栈元素 int max;//栈空间的最大值 int top;//栈顶 int size;//每个栈元素的大小 }STACK; STACK* stack_create(int max, int size);//初始化栈 void DestroyStack(STACK *stack);//销毁栈 int is_empty_stack(STACK *stack);//判断是否空栈 int is_full_stack(STACK *stack);//判断是否满栈 void stack_push(STACK *stack, void *data);//入栈,压栈 void *stack_pop(STACK *stack);//出栈,弹栈 void stack_travel(STACK *stack, stack_op_t ls);//遍历栈元素的函数, void ls(void *data);//打印栈元素的函数 #endif //__STACK_H__
//stack.c
#include "stack.h" //初始化栈,参数max代表最大值,size代表每个栈元素的大小 STACK *stack_create(int max, int size){ STACK *stack = (STACK*)malloc(sizeof(STACK)); if (NULL == stack){ goto Err; } stack->data = malloc(size * max); if (NULL == stack->data){ goto Err1; } stack->top = 0; stack->max = max; stack->size = size; return stack; Err: return NULL; Err1: free(stack); return NULL; } //销毁栈,stack代表栈的实例化 void DestroyStack(STACK *stack){ free(stack->data); free(stack); } //判断是否栈空,stakck同上 int is_empty_stack(STACK *stack){ if (stack->top == 0) return 1; else return 0; } //判断是否栈满,stack同上 int is_full_stack(STACK *stack){ if (stack->top == stack->max) return 1; else return 0; } //入栈,stakck同上,data是压栈的元素 void stack_push(STACK *stack, void *data){ if (is_full_stack(stack) == 1){ return ; } else { memcpy(stack->data + stack->top++ * stack->size, data, stack->size); } } //出栈,stakck同上 void *stack_pop(STACK *stack){ if (is_empty_stack(stack) == 1){ return NULL; } else { stack->top--; return stack->data + stack->top * stack->size; } } //遍历栈,stack同上,op是打印函数 void stack_travel(STACK *stack, stack_op_t op){ void *num = stack_pop(stack); while(NULL != num){ op(num); num = stack_pop(stack); } } //打印函数, data是需要打印的数据 void ls(void *data){ printf("%d ", *(int *)data); }
//test.c
#include "stack.h" int main(void){ STACK *stack = stack_create(MAX, sizeof(int));//1,初始化一个栈 int i, num; printf("push num : "); for (i = 0; i < MAX; i++){ num = i + 1; stack_push(stack, &num);//2,入栈 printf("%d ", num); } printf("\n================================\n"); printf("pop num : "); stack_travel(stack, ls);//3,遍历函数里出栈 printf("\n"); DestroyStack(stack);//4,销毁栈 return 0; }
链栈的实现:
//stack.h
#ifndef __STACK_H__ #define __STACK_H__ #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 10 typedef void (*stack_op_t)(int );//函数指针,指向打印栈元素的函数 typedef struct Stack{ int data; struct Stack *top; }STACK; STACK* stack_create(void); //初始化一个空栈 void DestroyStack(STACK *stack);//销毁栈 int is_empty_stack(STACK *stack);//判断是否空栈 STACK *stack_push(STACK *stack, int data);//入栈 STACK *stack_pop(STACK *stack, int *data);//出栈 void stack_travel(STACK *stack, stack_op_t ls);//遍历函数,并且打印 void ls(int data);//打印函数 #endif //__STACK_H__
//stack.c
#include "stack.h" STACK *stack_create(void){//初始化一个空栈 STACK *stack = (STACK *)malloc(sizeof(STACK)); if (NULL == stack){ goto Err; } stack->data = -1; stack->top = NULL; return stack; Err: return NULL; } void DestroyStack(STACK *stack){//销毁栈 free(stack); } int is_empty_stack(STACK *stack){//判断是否空栈 if (NULL == stack->top) { return 1; } else { return 0; } } STACK *stack_push(STACK *stack, int data){//入栈 STACK *new = (STACK *)malloc(sizeof(STACK)); if (NULL == new) return ; new->data = data; new->top = stack; stack = new; } STACK *stack_pop(STACK *stack, int *data){//出栈 if (is_empty_stack(stack) == 1){ return NULL; } *data = stack->data; STACK *new = stack; stack = stack->top; free(new); return stack; } STACK *stack_pop(STACK *stack, int *data){//出栈 if (is_empty_stack(stack) == 1){ return NULL; } *data = stack->data; STACK *new = stack; stack = stack->top; free(new); return stack; } void stack_travel(STACK *stack, stack_op_t op){//遍历栈 int data; while(stack->top){ stack = stack_pop(stack, &data); op(data); //打印 } } void ls(int data){//打印函数 printf("%d ", data); }
//test.c
#include "stack.h" int main(void){ STACK *stack = stack_create(); //1,初始化一个空栈 int i; printf("push : "); for (i = 0; i < 10; i ++){ stack = stack_push(stack, i + 1); //2, 入栈 printf("%d ", i + 1); } printf("\n====================\n"); printf("pop : "); stack_travel(stack, ls);//3,遍历栈,打印 printf("\n"); DestroyStack(stack);//4,销毁栈 return 0; }
因为是按照自己思路写的, 可能也有些地方没有考虑周全,如果朋友们看到有什么不妥的地方欢迎指出,十分乐意接受。
运行结果