李柱明博客:https://www.cnblogs.com/lizhuming/p/15487342.html
栈(stack)是限定仅在表尾进行插入和删除操作的线性表。
小笔记:
内存中的堆栈和数据结构堆栈不是一个概念:
内存中的堆栈是真实存在的物理区。内存空间在逻辑上分为三部分:代码区、静态数据区和动态数据区,动态数据区又分为栈区和堆区。
数据结构中的堆栈是抽象的数据存储结构。
栈相对于数组和链表来说只有限制,是操作受限的线性表。从功能上,数组和链表也可以代替栈,但是数组或链表暴露了太多的操作接口,操作上的确灵活自由,但使用时就比较不可控,自然也就更容易出错。
出栈序列个数公式:卡特兰公式:C(2n,n)/(n+1)
栈为线性表,具备线性表的操作特性。
对于栈来说,插入和删除改名为 push 和 pop。
// 指针式 typedef int se_type; /* 元素类型 */ typedef struct { se_type *top; /* 栈顶指针 */ se_type *bottom; /* 栈底指针 */ se_type stack_size; /* 栈的最大容量 */ }stack_t;
// 数组式 typedef int se_type; /* 元素类型 */ #define STACK_SIZE 100 /* 栈元素个数 */ typedef struct { int top; /* 栈顶指针 */ se_type data[STACK_SIZE]; /* 栈空间 */ }stack_t;
两栈共享空间:
原理:两个栈底分别位于数组的始端(下标 0)和数组的末端(下标数组长度 n-1),增加元素即从两端点向中间延伸。
条件:两个具有相同数据类型的栈,生长方向相反。
满栈判断:
top1+1 == top2
时。部分代码实现
// 数组式 /* 两栈共享空间结构 */ typedef int se_type; /* 元素类型 */ #define STACK_SIZE 100 /* 栈元素个数 */ typedef struct { int top1; /* 栈顶指针 */ int top2; /* 栈顶指针 */ se_type data[STACK_SIZE]; /* 栈空间 */ }stack_double_t; /** * @name stack_double_creat * @brief * @param * @retval * @author lzm */ stack_double_t *stack_double_creat(void) { stack_t *stack_double_ptr = NULL; stack_double_ptr = (stack_double_t *)malloc(sizeof(stack_double_t)); if(stack_double_ptr == NULL) return NULL; memset(stack_ptr, 0x00, sizeof(stack_double_t)); stack_double_ptr->top1 = -1; stack_double_ptr->top2 = STACK_SIZE; return stack_double_ptr; } /** * @name stack_double_destroy * @brief * @param * @retval * @author lzm */ int stack_double_destroy(stack_double_t *stack) { if(stack != NULL) { free(stack); return 0; } return -1; }
就是基于链表实现的栈。
栈的链式存储结构:
/* 链式结构 */ typedef int se_type; /* 元素类型 */ typedef struct stack_node { se_type date; struct stack_node *next; }stack_node_t; typedef struct { int count; stack_node_t *top; }stack_link_t;
递归的定义:
递归与栈结构:
/** @file stack.c * @brief 简要说明 * @details 详细说明 * @author lzm * @date 2021-09-06 09:42:22 * @version v1.0 * @copyright Copyright By lizhuming, All Rights Reserved * @blog https://www.cnblogs.com/lizhuming/ * ********************************************************** * @LOG 修改日志: ********************************************************** */ #include <stdio.h> #include <stdlib.h> #include <string.h> // 指针式 typedef int se_type; /* 元素类型 */ typedef struct { se_type *top; /* 栈顶指针 */ se_type *bottom; /* 栈底指针 */ se_type stack_size; /* 栈的最大容量,元素个数。 */ }stack_pointer_t; /** * @name stack_pointer_creat * @brief * @param * @retval * @author lzm */ stack_pointer_t *stack_pointer_creat(int size) { stack_pointer_t *stack_ptr = NULL; stack_ptr = (stack_pointer_t *)malloc(sizeof(stack_pointer_t)); if(stack_ptr == NULL) return NULL; memset(stack_ptr, 0x00, sizeof(stack_pointer_t)); stack_ptr->bottom = (se_type *)malloc(size * sizeof(se_type)); if(stack_ptr->bottom == NULL) { free(stack_ptr); return NULL; } memset(stack_ptr->bottom, 0x00, size * sizeof(se_type)); stack_ptr->top = stack_ptr->bottom; stack_ptr->stack_size = size; return stack_ptr; } /** * @name stack_pointer_destroy * @brief * @param * @retval * @author lzm */ int stack_pointer_destroy(stack_pointer_t *stack) { if(stack != NULL) { if(stack->bottom != NULL) free(stack->bottom); free(stack); return 0; } return -1; } /** * @name stack_pointer_clear * @brief * @param * @retval * @author lzm */ int stack_pointer_clear(stack_pointer_t *stack) { if(stack == NULL) return -1; stack->top = stack->bottom; return 0; } /** * @name stack_pointer_empty * @brief * @param * @retval * @author lzm */ int stack_pointer_empty(stack_pointer_t *stack) { if(stack == NULL) return -1; if(stack->top == stack->bottom) return 1; return 0; } /** * @name stack_pointer_full * @brief * @param * @retval * @author lzm */ int stack_pointer_full(stack_pointer_t *stack) { if(stack == NULL) return -1; if(stack->top == (stack->bottom + stack->stack_size * sizeof(se_type))) return 1; return 0; } /** * @name stack_pointer_length * @brief * @param * @retval * @author lzm */ int stack_pointer_length(stack_pointer_t *stack) { if(stack == NULL) return -1; return (stack->top - stack->bottom)/sizeof(se_type); } /** * @name stack_pointer_push * @brief * @param * @retval * @author lzm */ int stack_pointer_push(stack_pointer_t *stack, se_type elem) { if(stack_pointer_full(stack) != 0) return -1; *stack->top = elem; stack->top += sizeof(se_type); return 0; } /** * @name stack_pointer_pop * @brief * @param * @retval * @author lzm */ int stack_pointer_pop(stack_pointer_t *stack, se_type *elem) { if(stack_pointer_empty(stack) != 0) { elem = NULL; return -1; } stack->top -= sizeof(se_type); elem = stack->top; return 0; } int main(void) { ; }
/** @file stack.c * @brief 简要说明 * @details 详细说明 * @author lzm * @date 2021-09-06 09:42:22 * @version v1.0 * @copyright Copyright By lizhuming, All Rights Reserved * @blog https://www.cnblogs.com/lizhuming/ * ********************************************************** * @LOG 修改日志: ********************************************************** */ #include <stdio.h> #include <stdlib.h> #include <string.h> // 数组式 typedef int se_type; /* 元素类型 */ #define STACK_SIZE 100 /* 栈元素个数 */ typedef struct { int top; /* 栈顶指针 */ se_type data[STACK_SIZE]; /* 栈空间 */ }stack_t; /** * @name stack_creat * @brief * @param * @retval * @author lzm */ stack_t *stack_array_creat(void) { stack_t *stack_ptr = NULL; stack_ptr = (stack_t *)malloc(sizeof(stack_t)); if(stack_ptr == NULL) return NULL; memset(stack_ptr, 0x00, sizeof(stack_t)); stack_ptr->top = -1; return stack_ptr; } /** * @name stack_destroy * @brief * @param * @retval * @author lzm */ int stack_array_destroy(stack_t *stack) { if(stack != NULL) { free(stack); return 0; } return -1; } /** * @name stack_clear * @brief * @param * @retval * @author lzm */ int stack_array_clear(stack_t *stack) { if(stack == NULL) return -1; stack->top = -1; return 0; } /** * @name stack_empty * @brief * @param * @retval * @author lzm */ int stack_array_empty(stack_t *stack) { if(stack == NULL) return -1; if(stack->top == -1) return 1; return 0; } /** * @name stack_full * @brief * @param * @retval * @author lzm */ int stack_array_full(stack_t *stack) { if(stack == NULL) return -1; if(stack->top == STACK_SIZE-1) return 1; return 0; } /** * @name stack_length * @brief * @param * @retval * @author lzm */ int stack_array_length(stack_t *stack) { if(stack == NULL) return -1; return stack->top + 1; } /** * @name stack_push * @brief * @param * @retval * @author lzm */ int stack_array_push(stack_t *stack, se_type elem) { if(stack_array_full(stack) != 0) return -1; stack->top++; stack->data[stack->top] = elem; return 0; } /** * @name stack_pop * @brief * @param * @retval * @author lzm */ int stack_array_pop(stack_t *stack, se_type *elem) { if(stack_array_empty(stack) != 0 || elem == NULL) { return -1; } *elem = stack->data[stack->top]; stack->top--; return 0; } /** * @name stack_get_top * @brief * @param * @retval * @author lzm */ int stack_array_get_top(stack_t *stack, se_type *elem) { if(stack_array_empty(stack) != 0 || elem == NULL || stack->top >= STACK_SIZE) { return -1; } *elem = stack->data[stack->top]; return 0; }
/** @file stack.c * @brief 简要说明 * @details 详细说明 * @author lzm * @date 2021-09-06 22:52:12 * @version v1.0 * @copyright Copyright By lizhuming, All Rights Reserved * @blog https://www.cnblogs.com/lizhuming/ * ********************************************************** * @LOG 修改日志: ********************************************************** */ #include <stdio.h> #include <stdlib.h> #include <string.h> /* 链式结构 */ typedef int se_type; /* 元素类型 */ typedef struct stack_node { se_type date; struct stack_node *next; }stack_node_t; typedef struct { int count; stack_node_t *top; }stack_link_t; /** * @name stack_link_creat * @brief * @param * @retval * @author lzm */ stack_link_t *stack_creat(int size) { stack_link_t *stack_ptr = NULL; stack_ptr = (stack_link_t *)malloc(sizeof(stack_link_t)); if(stack_ptr == NULL) return NULL; memset(stack_ptr, 0x00, sizeof(stack_link_t)); stack_ptr->count = 0; stack_ptr->top = NULL; return stack_ptr; } /** * @name stack_link_destroy * @brief * @param * @retval * @author lzm */ int stack_link_destroy(stack_link_t *stack) { stack_node_t *stack_cur = NULL; stack_node_t *stack_last = NULL; if(stack == NULL) return -1; stack_cur = stack->top; while(stack_cur) { stack_last = stack_cur; stack_cur = stack_cur->next; free(stack_last); } free(stack); return 0; } /** * @name stack_link_clear * @brief * @param * @retval * @author lzm */ int stack_link_clear(stack_link_t *stack) { stack_node_t *stack_cur = NULL; stack_node_t *stack_last = NULL; if(stack == NULL) return -1; stack_cur = stack->top; while(stack_cur) { stack_last = stack_cur; stack_cur = stack_cur->next; free(stack_last); } return 0; } /** * @name stack_link_empty * @brief * @param * @retval * @author lzm */ int stack_link_empty(stack_link_t *stack) { if(stack == NULL) return -1; if(stack->count == 0) return 1; return 0; } /** * @name stack_link_length * @brief * @param * @retval * @author lzm */ int stack_link_length(stack_link_t *stack) { if(stack == NULL) return -1; return (stack->count); } /** * @name stack_link_push * @brief * @param * @retval * @author lzm */ int stack_link_push(stack_link_t *stack, se_type elem) { stack_node_t *stack_node_ptr = NULL; stack_node_ptr = (stack_node_t *)malloc(sizeof(stack_node_t)); if(stack_node_ptr == NULL) return -1; memset(stack_node_ptr, 0x00, sizeof(stack_node_t)); stack_node_ptr->date = elem; stack_node_ptr->next = stack->top; stack->top = stack_node_ptr->next; stack->count++; return 0; } /** * @name stack_link_pop * @brief * @param * @retval * @author lzm */ int stack_link_pop(stack_link_t *stack, se_type *elem) { stack_node_t *node = NULL; if(stack_link_empty(stack) != 0 || elem == NULL) { return -1; } *elem = stack->top->date; node = stack->top; stack->top = stack->top->next; free(node); stack->count--; return 0; } /** * @name stack_link_get_top * @brief * @param * @retval * @author lzm */ int stack_link_get_top(stack_link_t *stack, se_type *elem) { if(stack_link_empty(stack) != 0 || elem == NULL) { return -1; } *elem = stack->top->date; return 0; }