栈的操作(源码实现)
栈
栈(stack)又称为堆栈,是一种操作受限的线性表,拥有和线性表相同的逻辑结构。栈的限制只能在表的一端进行插入和删除操作,向一个栈新增一个元素叫进栈,让他称为栈顶元素。从一个栈删除元素叫出栈,使得下面的元素成为新的栈顶元素。
栈可以用单链表的操作一样,只是操作的时候只允许在一端操作,也申请一个头节点,如下,一个空栈,空栈的条件是head->next==NULL;
栈的操作只能在上面一头进行。
若入栈1,2,3,4, 5,如图::
入栈1,栈顶为1:
入栈2,栈顶为2:
入栈3,栈顶为3:
入栈4,栈顶为4:
入栈5,栈顶为5:
出栈的顺序是相反的:5–>4–>3–>2–>1。
相关源代码
mystack.h:
/**********************************
*Copyright(C),2010-2020,programer
*Filename:mystack.h
*Author:programer-L
*Description:stack some operator function
*Date:2020年8月12日
*Version: v1.0
**********************************/
#ifndef _MYSTACK_H_
#define _MYSTACK_H_
#define SUCCESS 0
#define ERROR -1
typedef int ElemType;
typedef struct stack_node {
int data;
struct stack_node *next;
}*PtrToNode;
typedef PtrToNode Stack;
/**********************************
*Function:create_stack
*Description:创建一个栈
*Input:
*Output:
*Return: 栈节点
*Others:
**********************************/
Stack create_stack();
/**********************************
*Function:push_stack
*Description:压栈
*Input:
*Output:
*Return:
*Others:
**********************************/
int push_stack(Stack s, int data);
/**********************************
*Function:pop_stack
*Description:出栈
*Input:
*Output:
*Return:
*Others:
**********************************/
int pop_stack(Stack s);
/**********************************
*Function:top_stack
*Description:取栈顶元素
*Input:
*Output:
*Return:
*Others:
**********************************/
int top_stack(Stack s);
/**********************************
*Function:show_stack
*Description:输出栈里元素
*Input:
*Output:
*Return:
*Others:
**********************************/
void show_stack(Stack s);
/**********************************
*Function:stack_is_empty
*Description:判断栈是否为空
*Input:
*Output:
*Return:
*Others:
**********************************/
int stack_is_empty(Stack s);
/**********************************
*Function:get_stack_num
*Description:获取栈元素个数
*Input:
*Output:
*Return:
*Others:
**********************************/
int get_stack_num(Stack s);
/**********************************
*Function:destory_stack
*Description:销毁栈
*Input:
*Output:
*Return:
*Others:
**********************************/
int destory_stack(Stack s);
#endif
mystack.c:
#include <stddef.h>
#include "mystack.h"
/* 创建一个空栈 */
Stack create_stack()
{
Stack S;
S = (Stack)malloc(sizeof(struct stack_node));
if (NULL == S)
{
printf("malloc fair!\n");
return NULL;
}
S->next = NULL;
return S;
}
/* PUSH 操作 */
int push_stack(Stack s,int data)
{
// 新建一个结点,用于存放压入栈内的元素,即新的栈顶
PtrToNode head_node = (PtrToNode)malloc(sizeof(struct stack_node));
if (head_node == NULL)
{
printf("malloc fair!\n");
return ERROR;
}
//类似于链表的头插法
head_node->data = data; // 添加数据
head_node->next = s->next; // 新的栈顶 head_node 的 next 指针指向原来的栈顶 s->next
s->next = head_node; // s->next 现在指向新的栈顶
return SUCCESS;
}
/* POP 操作 */
int pop_stack(Stack s)
{
PtrToNode head_node = (PtrToNode)malloc(sizeof(struct stack_node));
if (head_node == NULL)
{
printf("malloc fair!\n");
return ERROR;
}
// 先判断栈是否为空,若栈为空,则不能再进行出栈操作,报错
if (stack_is_empty(s))
{
printf("Error! Stack is empty!\n");
}
else
{
head_node = s->next; // head_node 为栈顶
s->next = head_node->next; // s->next 指向 head_node->next ,即新的栈顶
free(head_node); // 释放原来栈顶元素所占的内存
}
return SUCCESS;
}
/* 销毁栈 */
int destory_stack(Stack s)
{
Stack curnode;
for(; s!=NULL; )
{
curnode = s;
s = s->next;
free(curnode);
}
return SUCCESS;
}
/* 获取栈元素个数 */
int get_stack_num(Stack s)
{
int len = 0;
for(Stack curnode=s->next; curnode!=NULL; curnode=curnode->next)
{
len++;
}
printf("栈的个数是:%d\n", len);
return len;
}
/* 输出栈里元素 */
void show_stack(Stack s)
{
printf("stack elem is:");
for(Stack curnode=s->next; curnode!=NULL; curnode=curnode->next)
{
printf("%d ", curnode->data);
}
printf("\n");
}
/* 查看栈顶元素 */
int top_stack(Stack s)
{
if (stack_is_empty(s))
{
printf("Error! Stack is empty!\n");
return ERROR;
}
else
{
return s->next->data;
}
}
/* 判断栈是否为空 */
int stack_is_empty(Stack s)
{
return NULL == s->next;
}
main.c:
#include <stdio.h>
#include "mystack.h"
int main()
{
Stack stack = create_stack(); // 新建一个空栈
int top_data,i;
// 压栈操作,执行10次
for (i = 0;i < 10;i++) {
push_stack(stack, i);
}
show_stack(stack);
// 出栈操作,执行1次
pop_stack(stack);
// 返回栈顶元素的值
top_data = top_stack(stack);
printf("%d\n", top_data);
get_stack_num(stack);
destory_stack(stack);
return 0;
}
运行结果结果:
root@ubuntu:~/myvscode/list/stack# ./mystack stack elem is:9 8 7 6 5 4 3 2 1 0 8 栈的个数是:9
栈的应用
栈的应用十分广泛 ,在函数调用、中断处理、表达式求值、内存分配等操作中都需要用到栈。 假设有一个函数 f(),现在函数 f() 要调用函数 g() ,而函数 g() 又需要调用函数 h() 。当函数 f() 开始调用函数 g() 时,函数 f() 的所有局部变量需要由系统存储起来,否则被调用的新函数 g() 将会覆盖调用函数 f() 的变量;不仅如此,主调函数当前的位置也是需要保存的,以便被调函数执行完后知道回到哪里接着执行调用函数。同样的,函数 g() 调用函数 h() 时,g() 的相关信息也需要存储起来。在函数 h() 执行完成后,再从系统中取出函数 g() 的相关信息接着执行函数 g();当函数 g() 执行完成后,从系统中取出函数 f() 的相关信息然后接着执行函数 f()。从这里的描述中可以看到,函数调用时,调用函数的信息是存放在一个后进先出结构中的,显然,用栈来存放再好不过,用一幅图演示一下。
也可关注微信公众号,欢迎交流。