前篇文章已分析栈的顺序存储,以下分析栈的链式存储。并采取不同于上文的构建方式,实现入栈(push)、出栈(pop)、返回栈顶(peek)等操作。
1 结构体构建链表节点
typedef struct Node //链表节点构造
{
void *data; //数据域,传址,任意数据类型
struct Node *next; //指针域
} Node;
2 结构体构建栈
typedef struct Stack //栈
{
Node firstNode; //栈存储的首个链表节点
int size; //栈的大小
} Stack;
3 栈的初始化
Stack *initStack() //栈的初始化
{
Stack *stack = (Stack *)malloc(sizeof(stack)); //向堆区申请内存
if (stack == NULL)
return NULL; //内存申请失败返回NULL
stack->firstNode.next = NULL; //初始化
stack->firstNode.data = NULL;
stack->size = 0;
return stack;
}
4 节点入栈
int push(Stack *stack, void *data) //入栈,本质为头插插入节点
{
if (stack == NULL || data == NULL)
return 0;
Node *node = (Node *)malloc(sizeof(Node));
node->data = data;
node->next = NULL;
node->next = stack->firstNode.next; //有效首节点为firstNode.next
stack->firstNode.next = node;
stack->size++;
return 1;
}
5 出栈
void *pop(Stack *stack) //出栈,本质为删除首个有效节点
{
if (stack == NULL)
return NULL;
Node *popNode = stack->firstNode.next;//出栈节点
stack->firstNode.next = stack->firstNode.next->next;
stack->size--;
return popNode;
}
6 返回栈顶元素
void *peek(Stack *stack) //返回栈顶数据,单未删除
{
if (stack == NULL || stack->size == 0)
return NULL;
return stack->firstNode.next;
}
7 空栈判断
int isEmptyStack(Stack *stack) //判断是否栈空
{
if (stack == NULL)
return -1;
return stack->size == 0;
}
8 栈大小
int sizeOfStack(Stack *stack)//判断栈大小
{
if (stack == NULL)
return -1;
return stack->size;
}
9 释放栈
void destroyStack(Stack *stack)//释放栈
{
if (stack == NULL)
return;
free(stack);
stack = NULL;
}
10 测试与运行
#include <stdio.h>
#include <stdlib.h>
typedef struct Student//测试数据类型
{
int id;
char name[20];
} Student;
int main()
{
Student stuArray[] = {{1, "jakes1"}, {2, "jakes2"}, {3, "jakes3"}, {4, "jakes4"}, {5, "jakes5"}};
Stack *stack = initStack();
for (int i = 0; i < sizeof(stuArray) / sizeof(stuArray[0]); i++)
{
push(stack, &stuArray[i]);//Student数组依次入栈
Node *peekNode = (Node *)peek(stack);//peek栈顶
Student *stu = (Student *)peekNode->data;
printf("栈顶->id:%d name:%s\t 栈大小->size:%d\t 栈空(1为空)->%d\t\n", stu->id, stu->name, sizeOfStack(stack), isEmptyStack(stack));
}
while (!isEmptyStack(stack))
{
Node* popNode = pop(stack);
free(popNode);
popNode = NULL;
printf("栈大小->size:%d\t 栈空(1为空)->%d\t\n", sizeOfStack(stack), isEmptyStack(stack));
}
return 0;
}
运行结果如下: