栈
栈
1. 基本概念
栈是一种特殊的线性数据结构,它只允许在一端(通常是表尾)进行插入和删除操作,遵循后进先出(Last In First Out)的原则。

栈的主要特点:
- 后进先出(Last In First Out,简称LIFO)
- 只在一端进行操作
- 操作受限的线性表
基本概念:
- 栈顶(Top):表尾位置,是数据插入和删除的唯一位置
- 栈底(Base):表头位置
- 入栈:将新元素添加到栈顶的操作
- 出栈:从栈顶移除元素的操作
栈可以通过两种方式实现:
- 顺序栈(数组实现)
- 链式栈(链表实现)

时间复杂度分析:
- 出栈操作:O(1)
- 入栈操作:
- 最好情况:O(1)
- 最坏情况:O(n)(需要重新分配内存时)
2. 实现

共五个程序文件 sqstack.h、linksatck.h、sqstack.c、linksatck.c、main.c , 包括了顺序栈和链式栈
sqstack.h
typedef int data_t; // 定义数据类型
typedef struct
{
data_t *data;
int maxlen; // 栈最大长度
int top; // 栈顶-1标准栈为空
} sqstack_struct,*sqstack;
sqstack sqstack_create(int length); // 创建一个长度为length的栈,返回值为栈的指针
int sqstack_push(sqstack s, data_t x); // 元素x入栈,返回值为 0表示成功,-1表示失败
int sqstack_empty(sqstack s); // 判断栈是否为空,返回值为 1表示空,0表示非空
int sqstack_full(sqstack s); // 判断栈是否为满,返回值为 1表示满,0表示非满
data_t sqstack_pop(sqstack s); // 栈顶元素出栈,返回值为栈顶元素
data_t sqstack_top(sqstack s); // 返回栈顶元素,栈顶元素不变
int sqstack_clear(sqstack s); // 清空栈,返回值为 0表示成功,-1表示失败
int sqstack_free(sqstack s); // 释放栈,返回值为 0表示成功,-1表示失败
linksatck.h
typedef int data_t; // 定义数据类型
typedef struct node
{
data_t data; // 节点数据域
struct node *next; // 节点指针域
} linknode, *linkstack;
linkstack linkstack_create(); // 创建链栈,返回值 栈的地址
int linkstack_push(linkstack s, data_t x); // 入栈,返回值 0-成功,1-失败
int linkstack_pop(linkstack s); // 出栈,返回值 栈顶元素
int linkstack_empty(linkstack s); // 判断栈是否为空,返回值 1-空,0-非空
// int linkstack_full(linkstack *s); // 链栈动态存储,没有满这一说
data_t linkstack_top(linkstack s); // 获取栈顶元素,返回值 栈顶元素
linkstack linkstack_free(linkstack s); // 释放链栈,返回值NULL赋值给链栈
sqstack.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // for memset
#include "sqstack.h"
/**
* @name sqstack_create()
* @brief 创建顺序栈
* @param length 栈长
* @retval 栈地址
*/
sqstack sqstack_create(int length)
{
sqstack s;
// 1. 检查栈长参数是否合理
if (length < 0)
{
printf("length is invalid\n");
return NULL;
}
// 2. 申请栈空间,先申请栈结构体,然后申请data空间
if ((s = (sqstack)malloc(sizeof(sqstack_struct))) == NULL)
{
printf("malloc sqstack failed\n");
return NULL;
}
if ((s->data = (data_t *)malloc(length*sizeof(data_t))) == NULL)
{
printf("malloc sqstack->data failed\n");
free(s);
return NULL;
}
// 3. 初始化栈
memset(s->data, 0, length*sizeof(data_t));
s->maxlen = length;
s->top = -1;
return s;
}
/**
* @name sqstack_push()
* @brief 顺序栈入栈
* @param s 栈地址,x 入栈元素
* @retval 0 入栈成功,-1 入栈失败
*/
int sqstack_push(sqstack s, data_t x)
{
// 1. 检查栈是否存在以及栈是否满
if (s == NULL)
{
printf("sqstack is invalid\n");
return -1;
}
if (s->top == s->maxlen - 1)
{
printf("sqstack is full\n");
return -1;
}
// 2. 入栈
s->top++;
s->data[s->top] = x;
return 0;
}
/**
* @name sqstack_empty()
* @brief 顺序栈判断是否为空
* @param s 栈地址
* @retval 0 栈为空,-1 栈不为空
*/
int sqstack_empty(sqstack s)
{
// 1. 检查栈是否存在
if (s == NULL)
{
printf("sqstack is invalid\n");
return -1;
}
// 2. 通过栈顶判断栈是否为空
return(s->top == -1 ? 1 : 0);
}
/**
* @name sqstack_full()
* @brief 顺序栈判断是否满
* @param s 栈地址
* @retval 0 栈为满,-1 栈不满
*/
int sqstack_full(sqstack s)
{
// 1. 检查栈是否存在
if (s == NULL)
{
printf("sqstack is invalid\n");
return -1;
}
// 2. 通过栈顶判断栈是否为满
return(s->top == s->maxlen - 1 ? 1 : 0);
}
/**
* @name sqstack_pop()
* @brief 顺序栈出栈
* @param s 栈地址
* @retval 出栈元素
*/
data_t sqstack_pop(sqstack s)
{
// 1. 检查栈是否存在
if (s == NULL)
{
printf("sqstack is invalid\n");
}
// 2. 出栈
s->top--;
return s->data[s->top+1];
}
/**
* @name sqstack_top()
* @brief 顺序栈获取栈顶元素
* @param s 栈地址
* @retval 出栈元素
*/
data_t sqstack_top(sqstack s)
{
// 1. 检查栈是否存在
if (s == NULL)
{
printf("sqstack is invalid\n");
}
// 2. 返回栈顶元素
return s->data[s->top];
}
/**
* @name sqstack_clear()
* @brief 顺序栈清空
* @param s 栈地址
* @retval 0 清空成功,-1 清空失败
*/
int sqstack_clear(sqstack s)
{
// 1. 检查栈是否存在
if (s == NULL)
{
printf("sqstack is invalid\n");
return -1;
}
// 2. 清空栈。直接将栈顶置为-1,后续的入栈操作会覆盖原来的值。
s->top = -1;
return 0;
}
/**
* @name sqstack_free()
* @brief 顺序栈出栈
* @param s 栈地址
* @retval 0 释放成功,-1 释放失败
*/
int sqstack_free(sqstack s)
{
if (s == NULL)
{
printf("sqstack is invalid\n");
return -1;
}
if (s->data != NULL)
{
free(s->data);
}
free(s);
return 0;
}
linkstack.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linkstack.h"
/**
* @name linkstack_create()
* @brief 创建链式栈
* @param NULL
* @retval 栈顶地址
*/
linkstack linkstack_create()
{
// 1. 申请初始栈顶空间
linkstack s = (linkstack)malloc(sizeof(linkstack));
if ( s == NULL)
{
printf("malloc error\n");
return NULL;
}
// 2. 赋值,初始化栈顶空间
s->data = 0;
s->next = NULL;
return s;
}
/**
* @name linkstack_push()
* @brief 链式栈入栈
* @param s 栈顶地址, x 入栈元素
* @retval 0 入栈成功,-1 入栈失败
*/
int linkstack_push(linkstack s, data_t x)
{
// 1. 判断栈是否存在
if (s == NULL)
{
printf("linkstack is invalid\n");
return -1;
}
// 2. 申请新节点空间,并赋值,后续放置栈顶
linkstack newcode = (linkstack )malloc(sizeof(linkstack));
if ( newcode == NULL)
{
printf("newcode malloc error\n");
return -1;
}
newcode->data = x;
// 3. 将新节点放置栈顶(链表头部插入)
newcode->next = s->next;
s->next = newcode;
return 0;
}
/**
* @name linkstack_pop()
* @brief 链式栈入栈
* @param s 栈顶地址
* @retval 出栈元素
*/
int linkstack_pop(linkstack s)
{
linkstack tem_node;
data_t tem_value;
// 1. 判断栈是否存在和栈是否为空
if (s == NULL)
{
printf("linkstack is invalid\n");
return -1;
}
if (s->next == NULL)
{
printf("linkstack is NULL\n");
return -1;
}
// 2. 将元素出栈
tem_node = s->next;
tem_value = tem_node->data;
s->next = tem_node->next;
// 3. 释放内存,返回出栈元素
free(tem_node);
tem_node = NULL;
return tem_value;
}
/**
* @name linkstack_empty()
* @brief 链栈判断是否为空
* @param s 栈地址
* @retval 1 栈为空,0 栈不为空
*/
int linkstack_empty(linkstack s)
{
if (s == NULL)
{
printf("linkstack is invalid\n");
return -1;
}
return (s->next == NULL ? 1 : 0);
}
/**
* @name sqstack_top()
* @brief 链栈获取栈顶元素
* @param s 栈地址
* @retval 出栈元素
*/
data_t linkstack_top(linkstack s)
{
// 1. 判断栈是否存在和栈是否为空
if (s == NULL)
{
printf("linkstack is invalid\n");
return -1;
}
if (s->next == NULL)
{
printf("linkstack is NULL\n");
return -1;
}
// 2. 返回栈顶元素
return s->next->data;
}
/**
* @name sqstack_free()
* @brief 释放链栈
* @param s 栈地址
* @retval NULL 赋值给栈地址
*/
linkstack linkstack_free(linkstack s)
{
linkstack tem_node;
if (s == NULL)
{
printf("linkstack is invalid\n");
return NULL;
}
while (s != NULL)
{
tem_node = s;
s = s->next;
printf("free: %d\n", tem_node->data);
free(tem_node);
}
return NULL;
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "sqstack.h"
#include "linkstack.h"
void test_sqstack();
void test_linkstack();
int main(int argc, char *argv[])
{
test_sqstack();
test_linkstack();
return 0;
}
void test_sqstack()
{
sqstack s = sqstack_create(10);
sqstack_push(s, 30);
sqstack_push(s, 77);
sqstack_push(s, 97);
sqstack_push(s, 33);
sqstack_push(s, 99);
printf("top :%d\n", sqstack_top(s));
while (!sqstack_empty(s))
{
printf("%d\n", sqstack_pop(s));
}
sqstack_free(s);
printf("***SQSTACK TEST OVER****\n");
return;
}
void test_linkstack()
{
printf("\n");
printf("***LINKSTACK TEST START****\n");
linkstack s = linkstack_create();
linkstack_push(s, 30);
linkstack_push(s, 70);
linkstack_push(s, 90);
linkstack_push(s, 10);
linkstack_push(s, 23);
printf("top :%d\n", linkstack_top(s));
while (!linkstack_empty(s))
{
printf("%d\n", linkstack_pop(s));
}
s = linkstack_free(s);
return;
}

浙公网安备 33010602011771号