介绍下Leetcode简介:
算法题: 包含min函数的栈
代码:
#include <stdio.h>
#include <malloc.h>
typedef struct ListNode ListNode;//struct ListNode = ListNode
struct ListNode { //定义结构体
int data;
ListNode *next;//链表的指针域 结构体指针:结构体变量的地址,指向某个结构体变量(同时也是结构体变量中第一个元素的地址)
//结构体指针变量中的值是所指向结构体变量的地址
//我们可以通过结构体变量可以指向结构体中包含的一些成员
};
typedef struct Stack Stack;//struct Stack = Stack
struct Stack {
ListNode *top_node; //栈顶元素的指针 if 没有 struct ListNode = ListNode,那么ListNode *top_node = ListNode ListNode *top_node
int size;
};
//进栈
void stack_push(Stack* stack, int val) {
ListNode *new_node = (ListNode*)malloc(sizeof(ListNode)); // 1.新建节点。像操作系统申请一块内存,大小为ListNode,类型为ListNode *的空间给p指针变量,
/*sizeof(ListNode)计算ListNode所需要分配的空间大小
(ListNode*)malloc(...) 将返回的指针(void*)强制转换成ListNode**/
new_node->data = val; // 1,做相应赋值。结构体变量成员的访问 :结构体指针 ->成员名;如addr->country;
// (*结构体指针).成员名;(*addr).country;//很少去进行使用,注意必须去使用(),,因为*优先级大于.
// 结构体变量.成员名 stu.name
new_node->next = stack->top_node; //2,将新节点的next指针指向当前的栈顶元素。将新添加的指针域(结构体指针)指向栈的栈顶元素的地址,
stack->top_node = new_node;//3,将新节点设置为栈顶节点。使得新添加的节点变为栈顶元素
stack->size += 1;//4.修改栈中元素个数。
}
// 检验是否为空栈
int stack_is_empty(Stack *stack) {
return (stack->top_node == NULL); //若stack->top_node == NULL 返回 1
}
//得到栈顶元素值返回
int stack_top(Stack *stack) {
return stack->top_node->data; //stack->top_node->data 栈取栈顶元素值 相信为什么不能是stack.top_node.data
}
//删除栈顶元素
void stack_pop(Stack *stack) {
//判断栈顶元素是否为空
if (!stack->top_node) {
return;
}
ListNode *top_node = stack->top_node; //备份栈顶指针指向的节点地址
stack->top_node = stack->top_node->next;//修改栈顶指针,使其指向栈顶下方的元素
stack->size -= 1;//修改栈中元素个数
free(top_node);//释放原栈顶节点
}
//定义该栈:
typedef struct Minstack {
Stack min; //该栈存放的是当前栈栈最小元素
Stack data; //该栈存放的是当前栈顶元素
}Minstack;
//创造最小栈。相当于初始化在一个结构体下的两个结构体的值。
Minstack* minStackCreate(int maxSize) {
Minstack * new_stack = (Minstack*)malloc(sizeof(Minstack));
new_stack->min.top_node = NULL; // 结构体变量.成员名 使得结构体变量名为min的顶栈元素为NULL
new_stack->min.size = 0; // 使得结构体变量为min的节点数为0
new_stack->data.top_node = NULL; //结构体变量名为data的节点数为NULL
new_stack->data.size = 0;//结构体变量名为data的节点数为0
return new_stack;//返回 new_stack;
}
//进最小栈
void minStackPush(Minstack* obj,int x) {
Stack *data = &(obj->data); // 结构体指针变量初始化: 结构体指针变量名 = &结构体变量;或者:结构体指针变量名 = &(结构体变量.第一个成员)
Stack *min = &(obj->min);// 结构体指针必须要初始化以后才能够继续使用
stack_push(data, x); //在data结构体变量名中进栈
if (stack_is_empty(min)) { //判断min结构体变量名是否为空
stack_push(min, x); //为空则进值x到min栈
}
else { //if 不为空,则进行下面操作
if (x > stack_top(min)) { //if 加到data栈的x 比min栈的栈顶还大
x = stack_top(min); // if为真,则把min栈的栈顶赋值给x 。
}
stack_push(min, x); //把x推进栈min(比min栈大则原来小的栈顶还是栈顶,x就留在data作为栈顶了,若比它小,则把min栈顶赋值给x进min栈)
}
}
//删除栈栈顶
void minStackPop(Minstack* obj) {
stack_pop(&(obj->data));//删除结构体指针变量 结构体变量的地址,指向某个结构体变量(同时也是结构体变量中第一个元素的地址) 所以把栈顶元素删除了
stack_pop(&(obj->min)); //同上
}
//输出最小栈的栈顶
int minStackTop(Minstack* obj) {
return stack_top(&(obj->data));
}
//输出最小栈的最小值
int minStackGetMin(Minstack* obj) {
return stack_top(&(obj->min));
}
//释放最小栈
void minsStackFree(Minstack* obj) {
free(obj);
}
int main() {
Minstack *obj = minStackCreate(0);//创造一个结构体指针 将new_stack赋值给obj
minStackPush(obj, -2);//进-2 到栈obj
printf("top =[%d]\n", minStackTop(obj));
printf("min =[%d]\n\n", minStackGetMin(obj));
minStackPush(obj, 0);//进0 到栈obj
printf("top =[%d]\n", minStackTop(obj));
printf("min =[%d]\n\n", minStackGetMin(obj));
minStackPush(obj, -5);//进-5 到栈obj
printf("top =[%d]\n", minStackTop(obj));
printf("min =[%d]\n\n", minStackGetMin(obj));
minStackPop(obj);//删除栈min和栈data的栈顶
printf("top =[%d]\n", minStackTop(obj));//输出data栈栈顶
printf("min =[%d]\n\n", minStackGetMin(obj));//输出min栈最小栈
minsStackFree(obj);
return 0;
}
没有加注释,所以不是好代码。明儿有时间补上。(做到了!补上了!希望对你有帮助)
备注:有些知识需要补充下,关于结构体指针。
原因:
结果:
这张图可以加深理解。黑框里面分别是a的地址,a->next的地址,b的地址,b->next的地址。next指向下一个节点 就等于 next指向下一个节点 ,但是前一个节点的指针域存的就是下一个节点的地址、
知识点:
1.结构体指针的概念
概念:结构体变量的地址,指向某个结构体变量(同时也是结构体变量中第一个元素的地址)
结构体指针变量中的值是所指向结构体变量的地址
我们可以通过结构体变量可以指向结构体中包含的一些成员
定义一个结构体变量:
struct 结构体名 *结构体指针变量名;
如:struct address *addr;
- 1
- 2
- 3
结构体指针变量初始化:
结构体指针变量名 = &结构体变量;
或者:结构体指针变量名 = &(结构体变量.第一个成员)
- 1
- 2
- 3
注意:结构体指针必须要初始化以后才能够继续使用
2.结构体变量成员的访问
结构体指针 ->成员名;如addr->country;
(*结构体指针).成员名;(*addr).country;//很少去进行使用,注意必须去使用(),,因为*优先级大于.
结构体变量.成员名 stu.name
- 1
- 2
- 3
- 4
注意:如果是结构体指针的话,它是可以指向自己的(引用自己)
3.结构体指针的自引用
一个结构体内部包含一个指向该结构体本身的指针(必须是结构体指针)
struct Self{
int a;
int b;
struct Self *s; //必须是结构体指针,指向自身
}
关于结构体知识具体可以参考如下博客,十分详细:
https://blog.csdn.net/qq_29924041/article/details/54577724
感谢:来自四川成都的昌俊的悉心指导!
希望今日事情今日毕。
彩蛋: