C语言实现C语言实现顺序栈
简单描述
- 用codeblocks编译通过
- 源码参考连接
https://gitee.com/IUuaena/data-structures-c.git
代码
- seq_stack.h
c
#ifndef SEQ_STACK_H_INCLUDED
#define SEQ_STACK_H_INCLUDED
#define STACK_INIT_CAPACITY 100 //!< 栈初始容量
#define STACK_INCREMENT 10 //!< 栈容量增量
#define STACK_ELEM int //!< 栈结点类型
/*! @brief 函数返回值枚举 */
typedef enum Status
{
OK, //!< 正确
NON_ALLOCATED, //!< 内存分配失败
NON_EXISTENT, //!< 不存在
OVERFLOW, //!< 溢出
ERROR //!< 其他错误
} status_t;
/*! @brief 顺序栈 */
typedef struct
{
STACK_ELEM* elements; //!< 栈元素数组
STACK_ELEM* top; //!< 栈顶指针
int capacity; //!< 容量
int size; //!< 栈当前长度
} seq_stack_t;
// 顺序栈初始化
status_t SeqStackInit(seq_stack_t* seq_stack); // 构造一个空栈S
// 顺序栈销毁
status_t SeqStackDestroy(seq_stack_t* seq_stack); // 销毁栈S, S不再存在
// 顺序栈清空
status_t SeqStackClear(seq_stack_t* seq_stack); // 把S置为空栈
// 顺序栈是否为空
status_t SeqStackIsEmpty(seq_stack_t seq_stack); // 若栈S为空栈, 则返回TRUE, 否则返回FALSE
// 顺序栈长度
int SeqStackSize(seq_stack_t seq_stack); // 返回S的元素个数, 即栈的长度
// 顺序栈取栈顶
status_t SeqStackTop(seq_stack_t seq_stack, STACK_ELEM* top_elem); //
// 顺序栈入栈
status_t SeqStackPush(seq_stack_t* seq_stack, STACK_ELEM elem);
// 顺序栈出栈
status_t SeqStackPop(seq_stack_t* seq_stack, STACK_ELEM *elem);
// 顺序栈打印
void SeqStackPrint(seq_stack_t *seq_stack); // 打印队列
#endif // SEQ_STACK_H_INCLUDED
- seq_stack.c
c
/*!
* @file seq_stack.c
* @author CyberDash计算机考研, cyberdash@163.com(抖音id:cyberdash_yuan)
* @brief 栈 顺序栈
* @version 1.0.0
* @date 2022-07-10
* @copyright Copyright (c) 2021
* CyberDash计算机考研
*/
#include <stdlib.h>
#include <stdio.h>
#include "seq_stack.h"
/*!
* @brief **顺序栈初始化**
* @param seq_stack 顺序栈(指针)
* @return 执行结果
* @note
* 顺序栈初始化
* ----------
* ----------
*
* ----------
*
* top指向的地址并不存放栈元素, 是为了方便操作
*
* ----------
* - 数组elements分配内存\n
*   **if** 内存分配失败 :\n
*    返回NON_ALLOCATED\n
* - 栈属性初始化\n
*   top指向elements数组首地址\n
*   设置栈容量\n
*   栈内元素数0个\n
*/
status_t SeqStackInit(seq_stack_t* seq_stack)
{
// 为elements分配内存
seq_stack->elements = (STACK_ELEM*)malloc(STACK_INIT_CAPACITY * sizeof(STACK_ELEM));
if (!seq_stack->elements) // if 内存分配失败
{
return NON_ALLOCATED; // 返回NON_ALLOCATED
}
seq_stack->top = seq_stack->elements; // top指向数组首地址
seq_stack->capacity = STACK_INIT_CAPACITY; // 栈容量
seq_stack->size = 0; // 栈内元素数0个
return OK;
}
/*!
* @brief **顺序栈取栈顶**
* @param seq_stack 顺序栈
* @param top_elem 栈顶元素的保存变量(指针)
* @return 执行结果
* @note
* 顺序栈取栈顶
* ----------
* ----------
*
* ----------
*
* 读操作, 栈顶并不出栈
*
* ----------
* - 判断栈空\n
*   **if** 栈空 :\n
*    返回NON_EXISTENT\n
* - 赋值\n
*   将*(seq_stack.top - 1)赋给*top_elem\n
*/
status_t SeqStackTop(seq_stack_t seq_stack, STACK_ELEM* top_elem)
{
// ----- 判断栈空 -----
if (seq_stack.top == seq_stack.elements) // if 栈空
{
return NON_EXISTENT; // 返回NON_EXISTENT
}
// ----- 赋值 -----
*top_elem = *(seq_stack.top - 1); // 将*(seq_stack.top - 1)赋给*top_elem
return OK;
}
/*!
* @brief **顺序栈入栈**
* @param seq_stack 顺序栈(指针)
* @param elem 入栈元素
* @return 执行结果
* @note
* 顺序栈入栈
* --------
* --------
*
* --------
* - 判断栈满\n
*   **if** top - elements >= capacity :\n
*    elements重新分配内存\n
*    **if** 内存分配失败 :\n
*     返回NON_ALLOCATED\n
*    top指针重新指向最新的位置elements + capacity\n
*    capacity调整\n
* - 栈属性调整\n
*   入栈元素赋给top指针指向的位置\n
*   top指针向后移动一位\n
*   当前栈size增加1\n
*/
status_t SeqStackPush(seq_stack_t* seq_stack, STACK_ELEM elem)
{
// 栈满, 扩充elements数组, todo: 这里的>=包含两种边界条件, 需要增加case处理
if (seq_stack->top - seq_stack->elements >= seq_stack->capacity)
{
seq_stack->elements = (STACK_ELEM*)realloc(seq_stack->elements,
(seq_stack->capacity + STACK_INCREMENT) * sizeof(STACK_ELEM));
if (!seq_stack->elements)
{
return NON_ALLOCATED;
}
// top指针重新指向新位置
seq_stack->top = seq_stack->elements + seq_stack->capacity;
// capacity调整
seq_stack->capacity += STACK_INCREMENT;
}
*seq_stack->top = elem; // 入栈元素赋给top指针指向的位置
seq_stack->top++; // top指针向后移动一位
seq_stack->size++; // 当前栈size增加1
return OK;
}
/*!
* @brief **顺序栈出栈**
* @param seq_stack 顺序栈(指针)
* @param elem 栈顶元素
* @return 执行结果
* @note
* 顺序栈出栈
* --------
* --------
*
* --------
* - 判断栈空\n
*   **if** 栈空 :\n
*    返回NON_EXISTENT\n
* - 栈顶赋给elem\n
* - 栈属性调整\n
*   top指针向前挪1位(减1)\n
*   size减1\n
*/
status_t SeqStackPop(seq_stack_t* seq_stack, STACK_ELEM* elem)
{
if (seq_stack->top == seq_stack->elements)
{
return NON_EXISTENT;
}
*elem = *seq_stack->top;
seq_stack->top--;
seq_stack->size--;
return OK;
}
/*!
* @brief **顺序栈销毁**
* @param seq_stack 顺序栈
* @return 执行结果
* @note
* 顺序栈销毁
* ---------
* ---------
*
* ---------
* - free栈的elements\n
* - free栈\n
*/
status_t SeqStackDestroy(seq_stack_t* seq_stack)
{
free(seq_stack->elements);
free(seq_stack);
return OK;
}
/*!
* @brief **顺序栈清空**
* @param seq_stack 顺序栈
* @return 执行结果
* @note
* 顺序栈清空
* ---------
* ---------
*
* ---------
* **while loop** 栈不为空 :\n
*   Pop栈顶\n
*/
status_t SeqStackClear(seq_stack_t* seq_stack)
{
STACK_ELEM elem;
while (SeqStackIsEmpty(*seq_stack) != OK)
{
SeqStackPop(seq_stack, &elem);
}
return OK;
}
/*!
* @brief **顺序栈是否为空**
* @param seq_stack 顺序栈
* @return 执行结果
* @note
* 顺序栈是否为空
* ------------
* ------------
*
* ------------
* **if** top等于elements :\n
*   返回OK\n
* **else**\n
*   返回ERROR\n
*/
status_t SeqStackIsEmpty(seq_stack_t seq_stack)
{
if (seq_stack.top == seq_stack.elements)
{
return OK;
}
return ERROR; // todo: ERROR用的不好
}
/*!
* @brief **顺序栈长度**
* @param seq_stack 顺序栈
* @return 长度
* @note
* 顺序栈长度
* ---------
* ---------
*
* ---------
* 返回 top - elements
*/
int SeqStackSize(seq_stack_t seq_stack)
{
return seq_stack.top - seq_stack.elements;
}
/*!
* @brief **顺序栈打印**
* @param seq_stack 顺序栈
* @note
* 顺序栈打印
* ---------
* ---------
*
* ---------
* 遍历栈内元素, 打印
*/
void SeqStackPrint(seq_stack_t* seq_stack)
{
STACK_ELEM* cur = seq_stack->top;
printf("打印栈, 从栈顶到栈底\n");
while (cur - seq_stack->elements > 0)
{
printf("%d ", *(cur - 1));
cur--;
}
printf("\n");
}
- main.c
c
#include <stdio.h>
#include <stdlib.h>
#include "seq_stack.h"
/*!
* @brief **测试顺序栈插入**
* @note
*/
void TestSeqStackInsert()
{
printf("\n");
printf("|------------------------ CyberDash ------------------------|\n");
printf("| Test Insert |\n");
printf("| 测试栈插入 |\n");
seq_stack_t *sqStack = (seq_stack_t*)malloc(sizeof(seq_stack_t));
status_t res = SeqStackInit(sqStack);
if (res != OK)
{
printf("初始化栈失败");
}
SeqStackPush(sqStack, 1);
SeqStackPush(sqStack, 2);
SeqStackPush(sqStack, 3);
SeqStackPush(sqStack, 4);
SeqStackPush(sqStack, 5);
SeqStackPrint(sqStack);
printf("|-----------------------------------------------------------|\n\n");
}
/*!
* @brief **顺序栈清空**
* @note
*/
void TestSeqStackClear()
{
printf("\n");
printf("|------------------------ CyberDash ------------------------|\n");
printf("| Test SeqStackClear |\n");
printf("| 测试清除栈 |\n");
seq_stack_t sqStack;
status_t res = SeqStackInit(&sqStack);
if (res != OK)
{
printf("初始化栈失败");
}
SeqStackPush(&sqStack, 1);
SeqStackPush(&sqStack, 2);
SeqStackPush(&sqStack, 3);
SeqStackPush(&sqStack, 4);
SeqStackPush(&sqStack, 5);
res = SeqStackClear(&sqStack);
if (res == OK)
{
if (SeqStackIsEmpty(sqStack) == OK)
{
printf("清除栈成功\n");
}
}
printf("|-----------------------------------------------------------|\n\n");
}
/*!
* @brief **测试顺序栈长度**
* @note
*/
void TestSeqStackLength()
{
printf("\n");
printf("|------------------------ CyberDash ------------------------|\n");
printf("| Test Length |\n");
printf("| 测试栈长度 |\n");
seq_stack_t sqStack;
status_t res = SeqStackInit(&sqStack);
if (res != OK)
{
printf("初始化栈失败");
}
SeqStackPush(&sqStack, 1);
SeqStackPush(&sqStack, 2);
SeqStackPush(&sqStack, 3);
SeqStackPush(&sqStack, 4);
SeqStackPush(&sqStack, 5);
printf("栈长度: %d\n", SeqStackSize(sqStack));
printf("|-----------------------------------------------------------|\n\n");
}
/*!
* @brief 测试顺序栈栈顶
* @note
*/
void TestSeqStackTop()
{
printf("\n");
printf("|------------------------ CyberDash ------------------------|\n");
printf("| Test SeqStackTop |\n");
printf("| 测试获取栈顶 |\n");
seq_stack_t sqStack;
status_t res = SeqStackInit(&sqStack);
if (res != OK)
{
printf("初始化栈失败");
}
STACK_ELEM top;
SeqStackPush(&sqStack, 1);
SeqStackPush(&sqStack, 2);
SeqStackPush(&sqStack, 3);
SeqStackPush(&sqStack, 4);
SeqStackPush(&sqStack, 5);
SeqStackTop(sqStack, &top);
printf("栈顶: %d\n", top);
printf("|-----------------------------------------------------------|\n\n");
}
int main()
{
printf("顺序栈!\n");
TestSeqStackInsert();
TestSeqStackLength();
TestSeqStackClear();
TestSeqStackTop();
return 0;
}
运行结果
c
顺序栈!
|------------------------ CyberDash ------------------------|
| Test Insert |
| 测试栈插入 |
打印栈, 从栈顶到栈底
5 4 3 2 1
|-----------------------------------------------------------|
|------------------------ CyberDash ------------------------|
| Test Length |
| 测试栈长度 |
栈长度: 5
|-----------------------------------------------------------|
|------------------------ CyberDash ------------------------|
| Test SeqStackClear |
| 测试清除栈 |
清除栈成功
|-----------------------------------------------------------|
|------------------------ CyberDash ------------------------|
| Test SeqStackTop |
| 测试获取栈顶 |
栈顶: 5
|-----------------------------------------------------------|
Process returned 0 (0x0) execution time : 0.089 s
Press any key to continue.