1.栈
栈是一种受限制的数据结构,它只能在一端添加或者删除元素,符合先进先出(LIFO) 的特性
这个操作受限制是为了安全而考虑的,这样就能减少非法操作,并且适合生活中很多的场景
基本操作:
- 入栈
- 出栈
- 查看栈顶元素
- 判空
使用场景:
- 函数调用栈
- 符号匹配问题
- 表达式求值
- 深度优先搜索
实现代码
stack.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef struct node {
int val;
struct node* next;
}Node;
void stack_push(Node** pstack, int val);
int stack_pop(Node** pstack);
int stack_peek(Node* stack);//查看栈顶元素
bool stack_empty(Node* stack);
stack.c
#include"stack.h"
void stack_push(Node** pstack, int val) {
Node* newNode = malloc(sizeof(Node));
if (newNode == NULL) {
printf("malloc failed in stack_push\n");
exit(1);
}
//init
newNode->val = val;
newNode->next = *pstack;
*pstack = newNode;
}
int stack_pop(Node** pstack) {
//先进行判空
if (stack_empty(*pstack)) {
printf("stack is empty\n");
exit(1);
}
Node* moveNode = *pstack;
int moveVal = moveNode->val;
*pstack = moveNode->next;
free(moveNode);
return moveVal;
}
//查看栈顶元素
int stack_peek(Node* stack) {
if (stack_empty(stack)) {
printf("stack is empty\n");
exit(1);
}
return stack->val;
}
bool stack_empty(Node* stack) {
return (stack == NULL);
}
main.c
#include"stack.h"
int main() {
Node* stack = NULL;
stack_push(&stack, 1);
stack_push(&stack, 2);
stack_push(&stack, 3);
stack_push(&stack, 4);
//遍历
while (!(stack_empty(stack))) {
printf("%d ", stack_peek(stack));
stack_pop(&stack);
}
printf("\nstack is %s\n", stack_empty(stack) ? "EMPTY" : "NOT EMPTY");
return 0;
}
2.改变指针指向不传二级指针的方法
2.1传二级指针
总所周知:要在函数中改变变量的值需要传递改值的地址,即指向这个地址的指针,在链表中,我需要更改头节点的指向位置,通常就需要传递二级指针,因为该头节点就是一个指针
2.2不传二级指针改变指向
创建另一个结构体,用来存放头节点,尾节点的指针和链表长度,这样只用传递该结构体的指针就可以修改头节点的指向了,因为头节点和尾节点都在结构体中,传结构体的指针就可以改变结构体中的变量了,这也相当于是以二级指针的方式传递。