前面是用数组实现栈,现在考虑用链表来实现栈。
首先考虑先进后出这一原则,数据从哪头出最好?如果选择数组那样的结尾做栈顶,那么需要遍历整个链表才可以出栈入栈。所以最方便的还是让头结点作为栈顶。通过链表的next执行后续出栈入栈即可。
还是先在头文件中建立结构体:首先是链表是由结点构成,定义链表的结点数据结构体。然后是链表的结构体。包含头结点。然后增加一个size属性。
struct StackNode
{
struct StackNode *next;
};
struct LStack
{
struct StackNode header; //头结点
int size;
};
考虑到初始化时,我们对链表数据的保护,我们定义一种隐藏类型。
typedef void* LinkStack;
#pragma once
#include<stdlib.h>
#include"LinkList.h"
struct StackNode
{
struct StackNode *next;
};
struct LStack
{
struct StackNode header; //头结点
int size;
};
typedef void* LinkStack;
#ifdef __cplusplus
extern "C"{
#endif
//初始化
LinkStack Init_LinkStack();
//入栈
void Push_LinkStack(LinkStack stack, void *data);
//出栈
void Pop_LinkStack(LinkStack stack);
//获得栈顶元素
void* Top_LinkStack(LinkStack stack);
//获得大小
int Size_LinkStack(LinkStack stack);
//销毁栈
void Destroy_LinkStack(LinkStack stack);
#ifdef __cplusplus
}
#endif
代码实现
#include"LinkStack.h"
//初始化
LinkStack Init_LinkStack()
{
struct LStack *stack = malloc(sizeof(struct LStack));
if (NULL == stack)
{
return NULL;
}
stack->header.next = NULL;
stack->size = 0;
return stack;
}
//入栈
void Push_LinkStack(LinkStack stack, void *data)
{
if (NULL == stack)
{
return;
}
if (NULL == data)
{
return;
}
// 入栈参数先类型转换,然后把数据data也做转换赋值给链表的next。
struct LStack *ls = (struct LStack *)stack;
struct StackNode *node = (struct StackNode *)data;
node->next = ls->header.next;
ls->header.next = node;
++(ls->size);
}
//出栈
void Pop_LinkStack(LinkStack stack)
{
if (NULL == stack)
{
return;
}
//入栈参数链表先类型转换
struct LStack *ls = (struct LStack *)stack;
if (ls->size == 0)
{
return;
}
//缓存下第一个节点
struct StackNode *pFirst = ls->header.next;
// 出栈就是把头结点弹出去,将头结点的next做头结点。
ls->header.next = pFirst->next;
ls->size--;
}
//获得栈顶元素
void* Top_LinkStack(LinkStack stack)
{
if (NULL == stack)
{
return NULL;
}
struct LStack *ls = (struct LStack *)stack;
if (ls->size == 0)
{
return NULL;
}
return ls->header.next;
}
//获得大小
int Size_LinkStack(LinkStack stack)
{
if (NULL == stack)
{
return -1;
}
struct LStack *ls = (struct LStack *)stack;
return ls->size;
}
//销毁栈
void Destroy_LinkStack(LinkStack stack)
{
if (NULL == stack)
{
return;
}
free(stack);
stack = NULL;
}
验证代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"LinkStack.h"
struct Person
{
struct StackNode node;
char name[64];
int age;
};
void test()
{
//初始化栈
LinkStack stack = Init_LinkStack();
//创建数据
struct Person p1 = { NULL, "aaa", 10 };
struct Person p2 = { NULL, "bbb", 20 };
struct Person p3 = { NULL, "ccc", 30 };
struct Person p4 = { NULL, "ddd", 40 };
struct Person p5 = { NULL, "eee", 50 };
struct Person p6 = { NULL, "fff", 60 };
//数据入栈
Push_LinkStack(stack, &p1);
Push_LinkStack(stack, &p2);
Push_LinkStack(stack, &p3);
Push_LinkStack(stack, &p4);
Push_LinkStack(stack, &p5);
Push_LinkStack(stack, &p6);
//输出栈中所有元素
while (Size_LinkStack(stack) > 0)
{
//获得栈顶元素
struct Person *person = (struct Person *)Top_LinkStack(stack);
//打印
printf("Name:%s Age:%d\n", person->name, person->age);
//弹出栈顶元素
Pop_LinkStack(stack);
}
printf("Size:%d\n", Size_LinkStack(stack));
}
int main(){
test();
system("pause");
return EXIT_SUCCESS;
}