#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef char SElemType;
typedef struct StackNode
{
SElemType data; //存的数据
struct StackNode *next; //栈顶
}StackNode, *LinkStack;
LinkStack s; //指向栈顶(也是链表的头指针)
LinkStack InitStack(); //空栈构造函数
void DestroyStack(LinkStack s); //销毁栈函数
LinkStack ClearStack(LinkStack s); //清除栈
int StackEmpty(LinkStack s); //判断是否为空栈,是返回1,否 返回0
int StackLength(LinkStack s); //返回栈的长度
void Push(SElemType e); //入栈
SElemType Pop(); //出栈,删除栈顶元素并返回其值,否则返回ERROR
SElemType GetTop(LinkStack s); //返回栈顶元素
void StackTraverse(LinkStack s); //从栈底向栈顶访问每个元素
int main()
{
s = InitStack();
SElemType e,ch[15];
puts("请输入要入栈的字符串:");
// scanf("%s",ch1); //遇到空格会停止输入
gets(ch); //可以输入空格
for(int i=0;i<strlen(ch);i++){
printf("正在存入第 %d 个字符:%c\n",i+1,ch[i]);
Push(ch[i]); //入栈
}
printf("您的输入为(逆序):");
StackTraverse(s); //逆序访问每个元素
e = GetTop(s); //返回栈顶元素
printf("栈顶的元素为:%c\n",e);
printf("栈的长度为:%d\n",StackLength(s)); //栈长
printf("出栈元素为:");
while(!StackEmpty(s)){ //如果栈不为空就一直出栈
e = Pop();
printf("%c",e);
}
printf("\n------------------------\n");
//重新输入,测试清空栈
puts("请输入要入栈的字符串:");
gets(ch);
for(int i=0;i<strlen(ch);i++){
printf("正在存入第 %d 个字符:%c\n",i+1,ch[i]);
Push(ch[i]); //入栈
}
printf("您的输入为(逆序):");
StackTraverse(s);
s = ClearStack(s); //清空栈
printf("执行后的结果:");
StackTraverse(s);
DestroyStack(s); //销毁栈
return 0;
}
//1. 初始化
LinkStack InitStack()
{
LinkStack s = NULL;
printf("初始化链栈成功!\n");
return s;
}
//2. 销毁栈函数
void DestroyStack(LinkStack s)
{
LinkStack t;
while(s != NULL){
t = s;
s = s->next;
free(t);
}
printf("已销毁链栈!\n");
}
//3. 清除栈
LinkStack ClearStack(LinkStack s)
{
s = NULL; //直接将头指针(栈顶)置为空
printf("栈已清空!\n");
return s;
}
//4. 判断是否为空栈,是返回1,否 返回0
int StackEmpty(LinkStack s)
{
if(s == NULL)
return 1;
else
return 0;
}
//5. 返回栈的长度
int StackLength(LinkStack s)
{
int i=0;
LinkStack t=s;
while(!StackEmpty(t)){
t=t->next;
i++;
}
free(t);
return(i);
}
//6. 入栈
void Push(SElemType e)
{
StackNode *p;
p = (LinkStack)malloc(sizeof(StackNode)); //生成新结点
if(p != NULL){
p->data = e; //给新结点赋值
p->next = s; //将新结点插入栈顶
s = p; //s本身就指向栈顶,所以直接修改栈顶指针为p(p就是最后一个元素)
}
// printf("入栈成功!\n");
}
//7. 出栈,删除栈顶元素并返回其值
SElemType Pop()
{
SElemType e;
StackNode *p;
e = s->data; //返回删除的元素
p = s; //用于临时保存要删除的元素
s = s->next; //栈顶往前挪一位,看似是s->next,但实际上是指栈顶的前一个元素,因为链栈中指针的顺序为an->a1,单链表是a1->an
free(p); //删除原本栈顶的元素
return e;
}
//8. 返回栈顶元素
SElemType GetTop(LinkStack s)
{
if(s!=NULL)
return s->data;
printf("栈为空!\n");
}
//9. 从栈顶向栈底访问每个元素(逆序,顺序输出的话可以建立双向循环链表)
void StackTraverse(LinkStack s)
{
StackNode *p = s;
if(s == NULL)
{
printf("栈为空!\n");
return;
}
while(p!=NULL){
printf("%c",p->data);
p = p->next;
}
printf("\n");
}
运行结果