只是一个鶸用来记录学习内容的文章罢了,如果能多少帮到你那真是太好了,发现错误欢迎指正。
栈是一种先进后出的数据结构,链式栈顾名思义是链式存储的结构,可以理解为头节点为栈顶元素的链表,顺序栈用数组乱搞就行了主要记录下链式栈,后文统称链式栈为栈。
要想实现链式存储需要定义节点结构和栈结构。
struct node
{
int data;
struct node* next;
};
struct stack
{
struct node* top;
struct node* bottom;
int size;
};
每个栈都是struct stack* 类型的,栈中的每个元素都是struct node* 类型的,不仅需要为栈分配内存,还需要为压入栈中的元素分配内存。
node中的next指针用于让栈中上面的节点连接到下面的节点,stack中的top和bottom分别存放当前栈顶元素的地址和栈底元素的后一个位置的地址(NULL),因为是用于指向栈中节点的指针,所以得是struct node* 类型。
栈的操作大体上就是初始化,入栈,出栈,查看顶端元素和清空栈。
初始化栈
初始化栈只需要为指针分配内存然后设置一下栈内的初始化信息就好了。
struct stack* create_stack()
{
struct stack* s = (struct stack*)malloc(sizeof(struct stack));
s->size = 0;
s->top = s->bottom = NULL;
return s;
}
因为栈一开始是空的,所以top指针和bottom相等且为空,size自然也等于0。
入栈
入栈首先要将准备入栈的元素封装成节点,和链表无异。
struct node* create_node(int data)
{
struct node* new_node = (struct node*)malloc(sizeof(struct node));
new_node->data = data;
new_node->next = NULL;
return new_node;
}
之后入栈,根据栈的性质,新入栈的元素放在原栈顶元素之上,所以新的节点就应该在原先top指针指向的节点之上,即新节点的next应该连接到原栈顶节点。
在连接完成之后别忘了更新top指针指向的位置,同时size++。
void push(struct stack* s,int insert_number)
{
struct node* new_node = create_node(insert_number);
new_node->next = s->top;
s->top = new_node;
s->size++;
}
出栈
看完了入栈,出栈就很简单理解了,无非就是返回当前top指针指向的节点内的元素然后让top指针向下罢了。有两种方法,可以让函数直接返回元素值,也可以传入一个变量用于保存出栈的值,两种方法差别不大。
int pop(struct stack* s)
{
if(s->size == 0)
{
printf("栈空无法pop\n");
return -1;
}
struct node* temp = s->top;
s->top = s->top->next;
s->size--;
return temp->data;
}
void pop(struct stack* s,int* pop_number)
{
if(s->size == 0)
{
printf("栈空无法pop\n");
}
else
{
*pop_number = s->top->data;
s->top = s->top->next;
s->size--;
}
}
查看顶端元素
仅返回栈顶元素,不出栈
int top(struct stack* s)
{
return s->top->data;
}
清空栈
可以循环pop同时free掉空间。下面这样做更快,虽然不安全但是一般写题不用太过担心没有free的问题。
void clear(struct stack* s)
{
s->top = s->bottom;
s->size = 0;
}
贴上完整代码
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node* next;
};
struct stack
{
struct node* top;
struct node* bottom;
int size;
};
struct node* create_node(int data)
{
struct node* new_node = (struct node*)malloc(sizeof(struct node));
new_node->data = data;
new_node->next = NULL;
return new_node;
}
struct stack* create_stack()
{
struct stack* s = (struct stack*)malloc(sizeof(struct stack));
s->size = 0;
s->top = s->bottom = NULL;
return s;
}
void push(struct stack* s,int insert_number)
{
struct node* new_node = create_node(insert_number);
new_node->next = s->top;
s->top = new_node;
s->size++;
}
void pop(struct stack* s,int* pop_number)
{
if(s->size == 0)
{
printf("栈空无法pop\n");
}
else
{
*pop_number = s->top->data;
s->top = s->top->next;
s->size--;
}
}
//int pop(struct stack* s)
//{
// if(s->size == 0)
// {
// printf("栈空无法pop\n");
// return -1;
// }
// struct node* temp = s->top;
// s->top = s->top->next;
// s->size--;
// return temp->data;
//}
int top(struct stack* s)
{
return s->top->data;
}
void clear(struct stack* s)
{
s->top = s->bottom;
s->size = 0;
}
int main()
{
struct stack* s = create_stack();
int pop_number;
for(int i = 0;i < 6;i++)
{
push(s,i);
}
//clear(s);
//printf("%d",top(s));
while(1)
{
if(s->size == 0)
{
printf("栈已空\n");
break;
}
printf("%d ",pop(s));
//pop(s,pop_number);
//printf("%d ",pop_number);
}
return 0;
}