链栈存储结构
链栈的存储结构跟单链表相同,但是由于只能在栈顶执行插入和删除操作,显然以单链表的头部做栈顶最方便,不必要想单链表那样为了运算方便而附加头结点。
链栈的实现
#include<stdio.h>
#include<stdlib.h>
typedef int DataType;
//定义链栈的结构体
typedef struct Node{
DataType data;
struct Node * next;
}Node;
//初始化链栈
void InitStrack(Node ** top){
*top = NULL;
}
//链栈的销毁
void DestroyStrack(Node ** top){
Node * p;
while(*top != NULL){
p = *top;
*top = (*top)->next;
free(p);
}
}
//入栈操作
//头插法进行入栈
//C 语言传入函数如果传参为top指针,
//则在函数体内进行的头插操作会在函数体外无效果。
//简单来记:
//想用函数改变某变量,就传入某变值的指针。这里想改变top指针的指向,所以传入top的指针(地址)
//避免措施:
//1):函数返回值变为top类型的指针
//2):函数传参变为指向top的指针,即传入top指针的地址
void Push(Node ** top,DataType x){
printf("入栈操作前的top地址%p\n",*top);
Node * s = (Node *)malloc(sizeof(Node));
s->data = x;
s->next = *top;
*top = s;
printf("入栈操作后的top地址%p",*top);
printf("\n");
}
//出栈操作
int Pop(Node ** top,DataType * ptr){
printf("出栈操作前的top地址:%p\n",*top);
Node * p = *top;
if(top == NULL){
printf("下溢错误,删除失败\n");
return 0;
}
*ptr = (*top)->data;
*top = (*top)->next;
free(p);
printf("出栈操作后的top地址:%p\n",*top);
return 1;
}
//取栈顶元素
int GetTop(Node * top, DataType * ptr){
if(top == NULL){
printf("下溢错误,取栈顶失败\n");
return 0;
}
*ptr = top->data;
printf("函数中取栈顶元素%d\n",top->data);
return 1;
}
//判空操作
int Empty(Node * top){
printf("top指针地址%p\n",top);
if(top == NULL){
return 1;
}else{
return 0;
}
}
//链栈的使用
int main(){
DataType x;
Node * top = NULL;
InitStrack(&top);
printf("对10 20 30 40进行入栈操作\n");
Push(&top,10);
Push(&top,20);
Push(&top,30);
Push(&top,40);
if(GetTop(top,&x) == 1){
printf("取栈顶元素%d\n",x);
}
//进行出栈操作
if(Pop(&top,&x) == 1)
{
printf("出栈的元素为%d\n",x);
}
if(GetTop(top,&x) == 1){
printf("取栈顶元素%d\n",x);
}
if(Empty(top) == 1){
printf("栈为空\n");
}else{
printf("栈非空\n");
}
//链栈的销毁
DestroyStrack(&top);
if(Empty(top) == 1){
printf("栈为空\n");
}else{
printf("栈非空\n");
}
return 0;
}