目录
已测试运行正常。(vs2019)
text.c(含菜单)
后面的注释内容是对接口功能的测试。
#include"Stack.h"
void menu()
{
printf("***********************************\n");
printf("**0. 退出 1. 入栈 **\n");
printf("**2. 出栈 3. 删顶 **\n");
printf("**4. 打印 5. 栈长 **\n");
printf("**6. 判空 **\n");
printf("***********************************\n");
printf("***********************************\n");
}
int main()
{
Stack s1;
StackInit(&s1);
int input = 0;
do
{
menu();
printf("请选择:> ");
scanf("%d", &input);
switch (input)
{
case exiti:
{
StackDestroy(&s1);
printf("退出成功\n");
break;
}
case push:
{
StackData x = 0;
printf("请输入要入栈的数据\n");
scanf("%d", &x);
StackPush(&s1, x);
printf("入栈成功\n");
break;
}
case top:
{
StackData num = 0;
num= StackTop(&s1);
printf("栈顶元素为:>%d\n", num);
break;
}
case pop:
{
StackPop(&s1);
printf("删除栈顶成功\n");
break;
}
case show:
{
ShowStcak(&s1);
break;
}
case size:
{
printf("栈的长度为:%d\n", StackSize(&s1));
break;
}
case empty:
{
bool tmp = StackEmpty(&s1);
if (tmp == true)
{
printf("栈空\n");
}
else
{
printf("栈不为空\n");
}
break;
}
default:
{
printf("选择错误,请重新输入\n");
break;
}
}
} while (input);
return 0;
}
//void text1()
//{
// Stack s1;
//
// StackInit(&s1);
//
// StackPush(&s1, 1);
// StackPush(&s1, 2);
// StackPush(&s1, 3);
// StackPush(&s1, 4);
//
// ShowStcak(&s1);
//
// StackData num= StackTop(&s1);
// printf("num = %d\n", num);
//
// ShowStcak(&s1);
//
// StackData sz= StackSize(&s1);
// printf("sz= %d\n", sz);
//
// bool tmp = StackEmpty(&s1);
//
// StackDestroy(&s1);
//
// bool tmp1 = StackEmpty(&s1);
//
//}
//
//int main()
//{
// text1();
//
// return 0;
//}
Stack.c
各个接口的详细定义与描述
#include"Stack.h"
void StackInit(Stack* p)//栈的初始化
{
assert(p);//断言确认输入值为一个栈
p->data = NULL;
p->top = 0;
p->capacity = 0;
}
void StackPush(Stack* p, StackData x)//入栈(只能在栈顶出入),即应使用头插的思想
{
assert(p);
if (p->top == p->capacity)//相等则意味着栈已满,应该增容
{
int newcapacity = 0;
if (p->capacity == 0)//第一次容量为零是应该开辟默认大小的空间,否则开辟原来大小的二倍
newcapacity = SZ_DEFAULT;
else
newcapacity = 2 * p->capacity;
//容量已经确认,可以开辟新空间
StackData* ps = (StackData*)realloc(p->data, newcapacity * sizeof(StackData));
if (ps == NULL)
{
printf("StackPush::%s\n", strerror(errno));
exit(-1);
}//空间开辟失败,异常退出并报错
p->data = ps;
p->capacity = newcapacity;//新容量
}//空间已开辟成功,接下来进行头插
p->data[p->top] = x;
p->top++;
}
StackData StackTop(Stack* p)//取栈顶元素(出栈),注意取出后要删除最后一个元素
{
assert(p);
assert(p->top > 0);//栈不为空才能取出来
StackData num = p->data[p->top-1];//top是指向栈顶元素的下一个位置
p->top--;//完成出栈
return num;
}
int StackSize(Stack* p)//统计栈元素的个数
{
assert(p);
return p->top ;//top指向的是栈顶的下一个位置,也就意味着他的数值大小就是栈元素的个数
}
void StackPop(Stack* p)//删除栈顶元素
{
assert(p);
assert(p->top > 0);//断言栈空则无法进行删除
p->top--;//直接top-1,则已经无法访问到最后一个元素,完成删除
}
void ShowStcak(Stack* p)//打印栈的数据
{
assert(p);
assert(p->top > 0);//因为top指向的是栈最后一个数据的下一个位置
//当top等于零时意味着栈已经空了
int i = 0;
for (i = 0; i < p->top; i++)
{
printf("%d ", p->data[i]);
}
printf("\n");
}
void StackDestroy(Stack* p)//栈的销毁
{
assert(p);//空栈也可以销毁,所以不用考虑栈空的情况
free(p->data);
p->data = NULL;
p->capacity = 0;
p->top = 0;//其他数据恢复默认0
}
bool StackEmpty(Stack* p)//判断栈是否为空
{
assert(p);
return (p->top == 0);//top为零则是空
}
Stack.h
各个接口的声明.
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
#include<assert.h>
#include<stdbool.h>
enum
{
exiti,
push,
top,
pop,
show,
size,
empty
};
typedef int StackData;
#define SZ_DEFAULT 3//以宏的方式定义默认容量的大小
typedef struct Stack
{
StackData* data;
int top;//栈顶的位置,取栈顶的默认值为0
int capacity;//容量
}Stack;
//定义数组栈是,将数组的头部作为栈底,数组的尾部作为栈顶
//数据的插入和删除都只能在栈顶进行
//先入后出
void StackInit(Stack* p);//栈的初始化
void StackPush(Stack* p, StackData x);//入栈(只能在栈顶出入),即应使用尾插的思想
StackData StackTop(Stack* p);//取栈顶元素(出栈),注意取出后要删除最后一个元素
void StackPop(Stack* p);//删除栈顶元素
void ShowStcak(Stack* p);//打印栈的数据
int StackSize(Stack* p);//统计栈元素的个数
bool StackEmpty(Stack* p);//判断栈是否为空
void StackDestroy(Stack* p);//栈的销毁
后言
看到这里了点个赞喏宝子(⸝⸝⸝⋅⃘᷄ ·̭ ⋅⃘᷅⸝⸝⸝)♡