一、栈(stack)
1.1 概念
栈是一种先进后出的数据结构 FILO
2.1 栈的逻辑结构
线性结构,也就是说栈是线性表的一种。
2.3 栈的存储结构
1> 顺序存储
我们称之为顺序栈。
是基于数组实现的,一般会配合一个 "栈顶指针" top 来使用。
顺序栈本身相当于对顺序表操作的一个约束:只允许在同一端插入和删除元素。
2 > 链式存储
我们称为链式栈,是基于链表实现的,链式栈本身相当于对链表操作的一个约束:只允许在同一端插入和删除元素。
如果采用链表尾作为入栈和出栈的端点,那么入栈和出栈都需要遍历,时间复杂度都是O(n),所以一般链式栈都是使用链表头部进行 入栈和出栈 时间复杂度是 O(1)。
二、栈的操作
2.1 顺序栈的操作
1> 创建栈
2> 清空栈
3> 销毁栈
4> 向栈中插入元素:入栈/压栈(push)
5> 判断栈是否为满
6> 获取栈中的元素:出栈/弹栈(pop)
7> 判断栈是否为空
8> 打印栈中所有元素--学习阶段看现象用的
2.2 链式栈的操作
1> 创建栈
2> 清空栈
3> 销毁栈
4> 向栈中插入元素:入栈/压栈(push)
5> 获取栈中的元素:出栈/弹栈(pop)
6> 判断栈是否为空
7> 打印栈中所有元素--学习阶段看现象用的
三、栈的代码实现(以链式栈为例)
3.1 link_stack.h文件
#ifndef __LINK_STACK_H__
#define __LINK_STACK_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct _Node{
int data;
struct _Node *next;
}node_t;
typedef struct _Stack{
unsigned int count;
node_t *top;
}stack_t;
int create_stack(stack_t **my_stack);
int push_stack(stack_t *my_stack, int value);
int pop_stack(stack_t *my_stack, int *num);
int is_empty(stack_t *my_stack);
int clean_stack(stack_t *my_stack);
int destroy_stack(stack_t **my_stack);
int print_stack(stack_t *my_stack);
#endif
3.2 link_stack.c文件
#include "link_stack.h"
//创建栈
int create_stack(stack_t **my_stack){
if(NULL == my_stack){
printf("入参为NULL 请检查\n");
return -1;
}
*my_stack = (stack_t *)malloc(sizeof(stack_t));
if(NULL == *my_stack){
printf("内存分配失败\n");
exit(-1);
}
(*my_stack)->count = 0;
(*my_stack)->top = NULL;
return 0;
}
//入栈
int push_stack(stack_t *my_stack, int value){
if(NULL == my_stack){
printf("入参为NULL 请检查\n");
return -1;
}
//先创建新的 数据节点
node_t *pnew = (node_t *)malloc(sizeof(node_t));
if(NULL == pnew){
printf("内存分配失败\n");
exit(-1);
}
pnew->data = value;
pnew->next = NULL;
//将新节点头插到链表中
pnew->next = my_stack->top;
my_stack->top = pnew;
my_stack->count++;
return 0;
}
//出栈
int pop_stack(stack_t *my_stack, int *num){
if(NULL == my_stack){
printf("入参为NULL 请检查\n");
return -1;
}
if(is_empty(my_stack)){
printf("栈为空 出栈失败\n");
return -1;
}
//数据出栈
*num = my_stack->top->data;
//删除已经出栈数据的节点--头删
node_t *pdel = my_stack->top;
my_stack->top = pdel->next;
free(pdel);
pdel = NULL;
my_stack->count--;
return 0;
}
//判断栈是否为空 返回 1 空 返回 0 非空
int is_empty(stack_t *my_stack){
if(NULL == my_stack){
printf("入参为NULL 请检查\n");
return -1;
}
return my_stack->top == NULL ? 1 : 0;
}
//清空栈
int clean_stack(stack_t *my_stack){
if(NULL == my_stack){
printf("入参为NULL 请检查\n");
return -1;
}
node_t *pdel = NULL;
//循环头删 删除所有的 数据节点
while(NULL != my_stack->top){
pdel = my_stack->top;
my_stack->top = pdel->next;
free(pdel);
}
pdel = NULL;
//个数清零
my_stack->count = 0;
return 0;
}
//销毁栈
int destroy_stack(stack_t **my_stack){
if(NULL == *my_stack || NULL == my_stack){
printf("入参为NULL 请检查\n");
return -1;
}
//先调用清空
clean_stack(*my_stack);
free(*my_stack);
*my_stack = NULL;
return 0;
}
//遍历栈
int print_stack(stack_t *my_stack){
if(NULL == my_stack){
printf("入参为NULL 请检查\n");
return -1;
}
node_t *ptemp = my_stack->top;
while(NULL != ptemp){
printf("%d ", ptemp->data);
ptemp = ptemp->next;
}
printf("\n");
return 0;
}
3.3 main.c文件
#include "link_stack.h"
int main(){
stack_t *my_stack = NULL;
//创建栈
create_stack(&my_stack);
//数据入栈
push_stack(my_stack, 10);
push_stack(my_stack, 20);
push_stack(my_stack, 30);
//遍历栈
print_stack(my_stack);
//数据出栈
int num = 0;
pop_stack(my_stack, &num);
printf("num = %d\n", num);
pop_stack(my_stack, &num);
printf("num = %d\n", num);
pop_stack(my_stack, &num);
printf("num = %d\n", num);
pop_stack(my_stack, &num);
printf("num = %d\n", num);
//再入栈两个元素
push_stack(my_stack, 520);
push_stack(my_stack, 1314);
//遍历栈
print_stack(my_stack);
//清空栈
clean_stack(my_stack);
//遍历栈
print_stack(my_stack);
//销毁栈
destroy_stack(&my_stack);
printf("my_stack = %p\n", my_stack);
return 0;
}