顺序栈的实现–C 语言版,详细讲解+代码实现
例如:第一章 Python 机器学习入门之pandas的使用
前言
链栈,解决了顺序栈的长度有限问题和地址必须相邻问题。
一、结构体定义
一如既往,为方便操作,将结构体定义为两部分,一部分用来存储数据,另一部分用来装填地址,头节点的data仍然存储整个链栈的长度。
//定义
typedef struct Node{
int data;
struct Node* next;
}Node;
二、操作步骤
1.初始化
定义好一个头节点,将其data赋值为0,并将其指针置空。
//初始化
Node* init(){
Node* node = (Node*)malloc(sizeof(Node));
node->data=0;
node->next=NULL;
return node;
}
2.判断栈是否为空
通过头指针存储的data值或者通过头指针的next地址来判断是否为空,做出一个这种函数来方便之后操作。
//判断栈是否为空
int empty(Node* node){
if(node->data==0 || node->next==NULL){
return 1;
}else{
return 0 ;
}
}
3. 入栈操作
由于栈先进后出的特性,我们为了方便操作,将链栈的插入做成类似于单链表头插法的形式,在头插法下,新插入的数据结点将是离头节点最近的结点,当我们出栈操作的时候也直接操作首元结点即可。
步骤如下:
- 建立一个辅助结点prenode,将data赋给它的data变量
- 将prenode结点作为新的首元结点插入到头节点之后,剩下的结点一次后移
- 栈的长度+1
//入栈
void push(Node * node ,int data){
Node* curnode = (Node*)malloc(sizeof(Node));
curnode->data=data;
curnode->next = node->next;
node->next= curnode;
node->data++;
}
4. 出栈操作
由于我们入栈操作是类似于头插法一样的插入方法,所以当我们出栈的时候就并不需要太多循环遍历操作,直接对首元结点进行操作即可。
- 判断栈是否为空
- 当栈不为空的时候,将原本的首元结点地址替换为首元结点的下一个结点的地址即可
- 栈的长度-1
//出栈
void pop(Node* node){
if(!empty(node)){
Node* prenode = (Node*)malloc(sizeof(Node));
prenode = node->next;
node->next = prenode->next;
free(prenode);
node->data--;
}
}
5.遍历操作
遍历操作的方法有很多种,这边使用的是利用栈的长度进行操作的方法,直接利用之前单链表的方法对结点进行循环也一样,甚至可能更简单,观者可任意发挥。
- 首先判断栈是否为空
- 利用辅助结点和辅助变量进行循环输出。
//遍历
void print(Node* node){
if(empty(node)){
return;
}else{
Node* prenode=(Node*)malloc(sizeof(Node));
int i=1;
prenode = node->next;
while(i<=node->data){
printf("%d\n",prenode->data);
prenode = prenode->next;
i++;
}
}
}
6.运行
int main(){
Node* node = init();
push(node,24);
push(node,41);
push(node,67);
print(node);
printf("======================\n");
pop(node);
print(node);
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/0a2a72ff311b486c9ddec245281b0ecd.png)