数据结构—栈
什么是数据结构?
咱们在学习栈之前,得先明白什么是数据结构
数据结构:就是研究批量同类型元素之间的逻辑关系、存储方式以及处理算法的一门学科
批量同类型元素之间的逻辑关系:
1、集合关系(0对0)—多元素之间除了同属于一个集合之外,互相之间没有任何关系
2、线性关系(1对1)—任何元素只能有一个后继,有一个前驱,最后一个没有后继,最前面一个没有前驱(线性表)
3、树形关系(1对多)—任何一个元素可以有多个后继,但是只能有一个前驱
4、图形关系(多对多)—相当于地图一样
批量同类型元素之间的内存关系
1、顺序存储:在一块存储区域连续的存储多个同类型的元素
2、链式存储:每个元素都是结构体,每个元素被称为节点,每个元素和其他元素之间的内存不一定连续,每个元素中总有一个到两个指针类型的结构体成员指向其后继(或者后继和前驱)
批量同类型元素之间的算法
如:增、删、改、查、排序、遍历等
内存四区中的栈与数据结构的栈是一样的吗?
大家刚开始学习C语言的时候可能会有这样的困惑,内存四区中的栈和数据结构中的栈都是栈,那它们就是一样的。
但事实上他们是不一样的,通俗的的说,内存四区中的栈是真实存在的物理区,而数据结构中的栈只是抽象意义上的存储结构
什么是栈?
栈:是指一种特殊的线性表,插入和删除在同一端进行因此具备先进后出(FILO)的特性
栈按照存储方式又分为:
顺序栈:按顺序存储方式的栈
链式栈:按链式存储方式的栈
栈代码分析
以链式栈为例:
如果我们要写一个简单的链式栈的话,我们首先需要定义表示链表节点的结构体,以及表示栈的结构体
struct node{
int num;
struct node *next;
};//定义链表
struct stack{
struct node *p; //记录栈顶地址
int size; //记录栈内元素数量
};//定义栈
定义完栈和链表之后,我们需要创建链表和创建栈的函数,并将其初始化
//创建链表
struct node* creatNode(int data){
struct node* pnew = (struct node*)malloc(sizeof(struct node));
pnew -> next = NULL;
pnew -> num = data;
return pnew;
}
//创建栈
struct stack* creatStack(){
struct stack* myStack = (struct stack*)malloc(sizeof(struct stack));
myStack -> p = NULL;
myStack -> size = 0;
return muStack;
}
写完创建栈和链表的操作之后,接下来我们要做的就是对栈的元素进行入栈和出栈,因为栈是插入和移除都在同一侧,所以我们入栈选择头插法,并将栈顶地址指向每次新入栈的元素地址,这样就满足栈的先入后出的特点
//入栈
void in_stack(struct stack* pStack, int n){
struct node *pnew = creatNode(n);
pnew -> next = pStack;
pStack = pnew;
pStack -> size++;
return ;
}
//出栈
void out_stack(struct stack* pStack){
if(pStack -> size == 0){
printf("栈已经空了\n");
return;
}
else{
/*保存下一个节点的地址,然后移除当前节点,
将一下个节点地址赋值到当前栈顶地址上*/
struct node *pNode = pStack -> p -> next;
free(pStack -> p);
pStack -> p = pNode;
pStack -> size--;
return ;
}
}
//判断栈是否为空
int stackEmpty(struct stack *pStack){
if(pStack == 0){
return 0;
}
else{
return 1;
}
}
入栈和出栈的操作完成之后,最后就是通过主函数调用函数来实现一个栈的完整功能
int main(){
struct stack *myStack = creatStack();
/*分别将1、2、3入栈*/
in_stack(myStack, 1);
in_stack(myStack, 2);
in_stack(myStack, 3);
/*出栈并打印出栈的结果*/
while(stackEmpty(myStack)){
printf("%d -> ", myStack -> p -> num);
out_stack(myStack);
}
printf("\n");
}
最后的结果是(代码可能会有错误但上述步骤没问题):