前言
今天我们用非顺序储存结构(链表)实现一个栈,相比较于用顺序表实现,链表栈不需要预先分配好空间,故而在操作时就没有扩容这一步。头文件部分我们就不再过多赘述,先来分析一下我们需要哪些数据。因为我们打算用链表实现栈,所以节点是不可少的,而节点中又应该包括哪些数据呢?我们先回想一下链表的基本思想,要有储存数据的数据域data、用来连接的指针域*next,那么加上栈本身的长度size,我们可以将链表栈的结构体定义如下:
typedef struct Node{
eletype data; //数据域data、指针域*next
struct Node* next;
} Node;
typedef struct Stack{
Node* head; //为了方便后期的操作,我们设置一个头结点
int size;
} Stack;
1.栈的创建
创建栈(栈的初始化)仅需将栈结构体Stack中的相关变量进行初始化:
void StackCreat(Stack *stk){
stk->head=NULL;
stk->size=0;
}
在这里我们可以将链表栈的初始化和顺序表栈的初始化做个对比,因为少了动态分配空间这一步,所以在视觉上能看出链表栈要简单一些。
2.栈的销毁
栈的销毁同样比较简单,只要将相关元素归零就行:
void StackDestroy(Stack *stk){
while(stk->head){
Node* next=stk->head->next; //我们知道栈是先进后出,头指针是始终位于栈顶的
free(stk->head); //所以我们每次要释放的头结点的空间。释放完之后
stk->head=next; //需要更新头节点,所以在这里我们定义*next,来接收
} //未更新前的stk->head->next,之后再将其更新给head
stk->size=0;
}
3.入栈
入栈需要将新元素压入栈顶,故而在参数列表中要有Stack *stk、eletype element。完成这个操作我们可以新定义一个节点Node *new_node:
void StackPush(Stack *stk,eletype element){
Node* new_Node=(Node*)malloc(sizeof(Node)); //新定义的节点*new_node
new_Node->data=element; //将需要压入的element赋给数据域data
new_Node->next=stk->head; //关键的一步是更新头节点,用的是头插法
stk->head=new_Node;
stk->size++;
}
4.出栈
出栈是将位于栈顶的空间清空,并将栈顶元素的值带回,所以函数类型是eletype,在这里我们需要考虑栈为空的情况:
eletype StackPop(Stack *stk){
if(stk->head==NULL){
printf("Stack is empty!\n"); //判断头节点是否为空,即是否为空栈
exit(1);
}
int result=stk->head->data; //用result存下栈顶元素的值
Node* next=stk->head->next; //最后需要将头指针更新一下
free(stk->head); //当然栈的长度size同样要自减
stk->head=next;
stk->size--;
return result; //然后将需要删除的值带回
}
5.获取栈顶元素
获取栈顶元素比简单,只需要先判断是否为空,然后将栈顶元素返回:
eletype StackTop(Stack *stk){
return stk->head->data;
}
int StackGetsize(Stack *stk){
return stk->size;
}
6.获取栈的长度
int StackGetsize(Stack *stk){
return stk->size;
}
7.完整源码
#include <stdio.h>
#include <stdlib.h>
#define eletype int
typedef struct Node{
eletype data;
struct Node* next;
} Node;
typedef struct Stack{
Node* head;
int size;
} Stack;
void StackCreat(Stack *stk){
stk->head=NULL;
stk->size=0;
}
void StackDestroy(Stack *stk){
while(stk->head){
Node* next=stk->head->next;
free(stk->head);
stk->head=next;
}
stk->size=0;
}
void StackPush(Stack *stk,eletype element){
Node* new_Node=(Node*)malloc(sizeof(Node));
new_Node->data=element;
new_Node->next=stk->head;
stk->head=new_Node;
stk->size++;
}
eletype StackPop(Stack *stk){
if(stk->head==NULL){
printf("Stack is empty!\n");
exit(1);
}
int result=stk->head->data;
Node* next=stk->head->next;
free(stk->head);
stk->head=next;
stk->size--;
return result;
}
eletype StackTop(Stack *stk){
return stk->head->data;
}
int StackGetsize(Stack *stk){
return stk->size;
}
int main (){
Stack stk;
StackCreat(&stk);
StackPush(&stk,10);
StackPush(&stk,20);
StackPush(&stk,30);
StackPush(&stk,40);
StackPush(&stk,50);
StackPush(&stk,60);
printf("栈顶元素为:%d\n",StackTop(&stk));
printf("出栈:%d\n",StackPop(&stk));
printf("栈的大小为:%d\n",StackGetsize(&stk));
StackDestroy(&stk);
return 0;
}
结语
如有错误,敬请指出!