链式结构我的博客已经写完了,那么我就开始栈的内容了,栈的结构非常简单
就是后进先出的一种结构
堆栈可以通过数组或链表轻松实现。在这两种情况下,将数据结构标识为堆栈的不是实现,而是接口:只允许用户将项目弹出或推送到数组或链表上,几乎没有其他辅助操作。
这个博客我来实现链式栈,也巩固一下链表的写法:
链表栈大概是这样子的:
可以看到,使用无头链表就行
所以我们做一下准备工作,也是我们之前写链表经常有的一些基础
struct node {
int data;
struct node* next;
};
struct node* createnode(int data) {
struct node* newnode = (struct node*)malloc(sizeof(struct node));
newnode->data = data;
newnode->next = NULL;
return newnode;
}
上面栈的结构我已经画出来了
我们需要的是他的大小,他的栈顶对吧
那我们来用结构体给他封装一下
struct Stack {
int Stsize;
struct node* top;
};
struct Stack* createstack() {
struct Stack* newstack = (struct Stack*)malloc(sizeof(struct Stack));
newstack->Stsize = 0;//大小为零
newstack->top=NULL;//初始化,栈顶为空
return newstack;
}
我们下面写一下万金油的两个函数:是否为空,返回栈大小:
int size(struct Stack* pstack) {
return pstack->Stsize;
}
bool empty(struct Stack* pstack) {
return pstack->Stsize == 0;
}
添加栈顶元素就是无头链表的头节点插入法
void push(struct Stack* pstack, int data) {
struct node* newnode = createnode(data);
if (empty(pstack)){
pstack->top=newnode;//栈为空,插入的就是栈顶
}
else {
newnode->next = pstack->top;//创建的节点放在栈顶元素的上面,也就是
//新节点的下面的元素是原来的栈顶元素
pstack->top = newnode;//移动栈顶指针到新的节点
}
pstack->Stsize++;//这两种情况都得加元素个数,不然会出错
}
删除栈顶元素就是无头链表的头节点删除法
void pop(struct Stack* pstack) {
if (empty(pstack)) {
printf("栈为空");//栈为空,不能再删除,你是想把我榨干还是榨死
}
else {
struct node* deletenode = pstack->top;//无头链表的删除都需要保存一下删除的节点
pstack->top = deletenode->next;//移动栈顶到下面的元素
free(deletenode);//释放申请的头节点指针指向的节点的内存
}
pstack->Stsize--;
}
得到栈顶元素就是返回它的栈顶指针指向的节点指向的数据:
int gettop(struct Stack* pstack) {
if (empty(pstack)) printf("栈为空");
else {
return pstack->top->data;
}
}
下面我们试一下我们写出来的链式栈的入栈出栈,和打印栈的元素
int main() {
struct Stack* mystack = createstack();//创建栈的函数
push(mystack, 2);//压入2
push(mystack, 3);//压入3
push(mystack, 4);//压入4
while (!empty(mystack)) {//只要不为空我们就运行
int i = gettop(mystack);//栈顶的元素
printf("%d\t", i);//打印栈顶的元素
pop(mystack);//打印的栈顶元素出栈才会达到栈空的情况
}
}
可以看到输出结果为 4 3 2;
是倒着输出的
下面我们看一下简单的一个示例:
计算一个十进制数的二进制数,num=2222;
(我这里添加到以上的主函数的后面)
struct Stack* s = createstack();
int num = 2222;
while (num) {
push(s, num % 2);
num /= 2;
}
while (!empty(s)) {
int i = gettop(s);
printf("%d", i);
pop(s);
}
看我的主函数输出:
可以看到计算结果正确
所以,今天的链式栈,你学会了么?