链栈:
- 存储结构采用链式存储的栈被称为链栈
- 优点:提高存储空间的利用率,且不存在栈满溢出的情况
- 特点:常采用单链表实现,规定所有操作在链表的表头进行
- 分类:带头结点,不带头结点
代码分块:
1.结构体构建
typedef struct LinkNode{
int data;//数据域
struct LinkNode *next;//指针域
}*LinkStack;//链栈结构体
2. 栈顶指针初始化
void InitStack(LinkStack *S){
*S = NULL;//栈顶指针初始化
}
3.入栈操作
bool PushStack(LinkStack *S,int pushNum){//入栈操作
LinkStack Point;//定义一个指针
Point = (LinkStack)malloc(sizeof(LinkNode));//创建一个结点
Point->data = pushNum;//结点赋值
Point->next = *S;//新结点后继指针指向栈顶指针指向的结点
*S = Point;// 栈顶指针指向新结点
}
4.出栈操作
bool PopStack(LinkStack *S,int *popNum){//出栈操作
LinkStack agency;
agency = (LinkStack)malloc(sizeof(LinkNode));//创建一个结点
agency = *S;//该结点指向栈顶指针
if(agency==NULL){//当该节点为空时,整个链栈为空
return false;
}
*popNum = agency->data;//记录出栈元素
*S = agency->next;//栈顶指针下移
return true;
}
5.遍历栈
void TraversalStack(LinkStack *S){//遍历链栈
LinkStack TraversalPoint;//定义一个指针
int record = 0;
TraversalPoint = (LinkStack)malloc(sizeof(LinkNode));//创建一个结点
TraversalPoint->next = *S;//使该结点指向栈顶指针所指的结点
while(TraversalPoint->next!=NULL){//当遍历结点的下一个结点为空时,遍历结束
TraversalPoint = TraversalPoint->next;//遍历指针指向下一个结点
record=TraversalPoint->data;//记录结点内容
printf("%d\n",record);
}
}
6.读取栈顶元素
bool GetTop(LinkStack *S){//读取栈顶元素
int popNum = 0;
LinkStack agency;
agency = (LinkStack)malloc(sizeof(LinkNode));//创建一个结点
agency = *S;//该结点指向栈顶指针
if(agency==NULL){
printf("栈已经空了");
return false;
}
popNum = agency->data;//记录出栈元素
printf("栈顶元素为:%d\n",popNum);
return true;
}
完整代码:
//不带头结点的链栈
#include <stdio.h>
#include <stdlib.h>
typedef struct LinkNode{
int data;//数据域
struct LinkNode *next;//指针域
}*LinkStack;//链栈结构体
void InitStack(LinkStack *S){
*S = NULL;//栈顶指针初始化
}
bool PushStack(LinkStack *S,int pushNum){//入栈操作
LinkStack Point;//定义一个指针
Point = (LinkStack)malloc(sizeof(LinkNode));//创建一个结点
Point->data = pushNum;//结点赋值
Point->next = *S;//新结点后继指针指向栈顶指针指向的结点
*S = Point;// 栈顶指针指向新结点
}
void TraversalStack(LinkStack *S){//遍历链栈
LinkStack TraversalPoint;//定义一个指针
int record = 0;
TraversalPoint = (LinkStack)malloc(sizeof(LinkNode));//创建一个结点
TraversalPoint->next = *S;//使该结点指向栈顶指针所指的结点
while(TraversalPoint->next!=NULL){//当遍历结点的下一个结点为空时,遍历结束
TraversalPoint = TraversalPoint->next;//遍历指针指向下一个结点
record=TraversalPoint->data;//记录结点内容
printf("%d\n",record);
}
}
bool PopStack(LinkStack *S,int *popNum){//出栈操作
LinkStack agency;
agency = (LinkStack)malloc(sizeof(LinkNode));//创建一个结点
agency = *S;//该结点指向栈顶指针
if(agency==NULL){//当该节点为空时,整个链栈为空
return false;
}
*popNum = agency->data;//记录出栈元素
*S = agency->next;//栈顶指针下移
return true;
}
bool GetTop(LinkStack *S){//读取栈顶元素
int popNum = 0;
LinkStack agency;
agency = (LinkStack)malloc(sizeof(LinkNode));//创建一个结点
agency = *S;//该结点指向栈顶指针
if(agency==NULL){
printf("栈已经空了");
return false;
}
popNum = agency->data;//记录出栈元素
printf("栈顶元素为:%d\n",popNum);
return true;
}
int main(){
LinkStack S;//声明一个指向链栈栈顶的指针
InitStack(&S);//初始化链栈
//入栈操作
int pushNum = 0;//入栈元素
printf("请输入入栈元素:");
scanf("%d",&pushNum);
while(pushNum != 99){//当输入99时停止
PushStack(&S,pushNum);//入栈
printf("\n请输入入栈元素:");
scanf("%d",&pushNum);
}
TraversalStack(&S);//遍历栈内元素
//出栈操作
bool flag = true;
int popNum = 0;//存储出栈元素的变量
char elect = NULL;//判断是否继续出栈的变量
printf("是否出栈元素(y|x):");
scanf("%s",&elect);
while(elect == 'y'){
flag = PopStack(&S,&popNum); //调用出栈操作
if(flag == false){
printf("\n栈已空");
exit(0);
}else{
printf("\n出栈元素为%d",popNum);
}
printf("\n是否出栈元素(y|x):");
scanf("%s",&elect);
}
TraversalStack(&S);//遍历栈内元素
//读栈顶元素
GetTop(&S);
}
运行结果展示: