刚学习到数据结构的链栈,以此做个记录,防止忘记以及帮助迷的人
链栈主要实现功能:
**Status Stack_Init(StackNodePtr s);//初始化栈
void Stack_Destroy(StackNodePtr s);//销毁栈
int Length_Stack(StackNodePtr s);//元素个数
bool Stack_Empty(StackNodePtr s);//栈空判断
Status Stack_Top(StackNodePtr s,ElemType elem);//取出栈顶元素
Status Stack_Push(StackNodePtr s, ElemType elem);//入栈
Status Stack_Pop(StackNodePtr s, ElemType elem);//出栈,出栈元素返回
Status Stack_Print(StackNodePtr s);//打印栈中元素
忽略status带来的效果,并没有什么用
说明都写在注释里面了
如有错误麻烦指出,谢谢!
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
typedef int ElemType;
enum Status {
success, overflow, fail, underflow
};//这些可以忽略!!
typedef struct StackNode {
ElemType data;
struct StackNode *next;
}StackNode, *StackNodePtr;//定义链栈结构体,和结构体指针
Status Stack_Init(StackNodePtr s);//初始化栈
void Stack_Destroy(StackNodePtr s);//销毁栈
int Length_Stack(StackNodePtr s);//元素个数
bool Stack_Empty(StackNodePtr s);//栈空判断
Status Stack_Top(StackNodePtr s,ElemType *elem);//取出栈顶元素
Status Stack_Push(StackNodePtr s, ElemType elem);//入栈
Status Stack_Pop(StackNodePtr s, ElemType *elem);//出栈,出栈元素返回
Status Stack_Print(StackNodePtr s);//打印栈中元素
Status Stack_Init(StackNodePtr s) {
Status status = fail;//这类东西忽略即可,写了也没用上
if (s != NULL) {
s->next = NULL;//初始化链栈,让其头节点的指针域指向空
status = success;
}
return status;
}
Status Stack_Push(StackNodePtr s, ElemType elem) {
//链栈的实现方式与链表的头插法一致,看不懂可以画图来试试(有奇效)
StackNodePtr p;
p = (StackNodePtr)malloc(sizeof(StackNode));//开辟新节点来保存数据
p->data = elem;
p->next = s->next;//先插入的反而在最后面,当p是第一个节点的时候就让p的指针域指向的空,
//正好完成了一个链栈结构
s->next = p;//让头节点移动到第一个节点,当出现第二个节点的时候上一条语句就会让其指向第一个节点
return success;
}
Status Stack_Print(StackNodePtr s) {
if (s->next == NULL) {
printf("链栈为空!\n");
return fail;
}
StackNodePtr p;
p = s->next;//让p指向第一个节点,链栈打印,逐一遍历
while (p != NULL) {
printf("%d\t", p->data);
p = p->next;
}
printf("\n");
return success;
}
void Stack_Destroy(StackNodePtr s) {
if (!s->next) {
printf("链栈不存在!\n");
return;
}
StackNodePtr p = s->next;
while (p != NULL) {
StackNodePtr t = p;//临时变量t来保存当前节点
p = p->next;//p接着指向下一个节点
free(t);
}
s->next = NULL;//实践发现并不能free掉s,所以只能让他的指针域指向NULL,没查出来原因
//有知道的可以说一下
printf("链栈已销毁!\n");
}
int Length_Stack(StackNodePtr s) {
int len = 0;
StackNodePtr p = s->next;
while (p) {//从第一个节点遍历到最后一个节点
len++;
p = p->next;
}
return len;
}
bool Stack_Empty(StackNodePtr s) {
return s->next == NULL;
}
Status Stack_Top(StackNodePtr s, ElemType *elem) {
Status status = fail;
if (s->next != NULL) {
status = success;
*elem = s->next ->data;//取出栈顶元素
}
return status;
}
Status Stack_Pop(StackNodePtr s,ElemType *elem) {
Status status = fail;
if (s->next == NULL) {
printf("栈为空!\n");
return status;
}
StackNodePtr p = s->next;//指向栈顶
*elem = p->data;//取出栈顶的数据域
s->next = p->next;//pop掉栈顶元素,只需要让s的指针域指向下下个节点
free(p);//释放掉当前节点,节省空间
return status;
}
int main() {
system("color 9F");//看起来舒服的颜色......
StackNode s;//定义一个节点
if (Stack_Init(&s) == success) printf("链栈初始化成功!");
else {
printf("链栈初始化失败!");
return 0;
}
//存留下来的测试环节...
puts("开始输入链栈的数据(0结束):");
ElemType x;
while (1) {
scanf("%d", &x);
if(x) Stack_Push(&s, x);
else break;
}
Stack_Print(&s);
Stack_Pop(&s, &x);
printf("pop出的元素为:%d\n", x);
Stack_Print(&s);
}