最小栈和栈的区别就是,在时间复杂度为O(1)的情况下获取当前栈内元素的最小值。
下面是我的分析流程图:
这里出现了一个万一数组内元素重复出现的情况,我的思路与如下:
- 1>正常情况下,我们考虑如果当前需要插入的值和最小栈顶值相同,那我们继续将该值插入最小栈中,(如果不这样做的话,你出栈时,前面的最小值出去了,而此时最小栈的栈顶元素不符合当前所需的最小值)
- 2>万一特殊情况,相同的值有好多。比如有一万个,那我们不可能都插进去,那样太耗费空间了,这样我们就考虑用一个专门的计数数组,而这个数组的每个数值表示每次最小值得个数。如下图
上面只是我提供的思路:
下面来看我的代码实现
具体代码实现:
[test@localhost mianshi]$ ls
Makefile stack stack.c stack.h
stack.h:
#pragma once
#include <stdio.h>
#include <stdlib.h>
#define DataType int
#define LINE printf("------------%s------------\n",__FUNCTION__);
#define stackMaxSize 100//定义当前栈的最大值
typedef struct stack{
DataType* arr;
size_t size;
}stack;
void stackInit(stack* head);
void stackPush(stack* head,stack* root,DataType value);
void stackPop(stack* head,stack* root);
DataType getmin(stack* root);
stack.c:
#include "stack.h"
//初始化
void stackInit(stack* head)
{
if(head == NULL)
{
return;
}
head->arr = (DataType*)malloc(stackMaxSize * sizeof(DataType));
if(head->arr == NULL)
{
perror("malloc");
return;
}
head->size = 0;
}
//入栈
void stackPush(stack* head,stack* root,DataType value)
{
if(head == NULL || root == NULL)
{
return;
}
if(head->size == 0)//空栈时候
{
head->arr[head->size] = value;
++(head->size);
root->arr[root->size] = value;
++(root->size);
}
else
{
//待插入的值比最小栈的栈顶小
if(root->arr[root->size-1] >= value)
{
head->arr[head->size] = value;
++(head->size);
root->arr[root->size] = value;
++(root->size);
}
else
{
head->arr[head->size] = value;
++(head->size);
}
}
}
//出栈
void stackPop(stack* head,stack* root)
{
if(head == NULL || root == NULL)
{
return;
}
if(head->size == 0 || root == NULL)
{
return;
}
//判断当前的出栈是不是和最小栈的栈顶元素相等
if(head->arr[head->size] == root->arr[root->size])
{
--(head->size);
--(root->size);
}
else
{
--(head->size);
}
}
//获取最小值
DataType getmin(stack* root)
{
if(root == NULL)
{
return 0;
}
if(root->size == 0)
{
return 0;
}
return root->arr[root->size-1];
}
//-----------------------------------------------------------------
//---------测试函数
//-----------------------------------------------------------------
void stackprint(stack* head,stack* root)
{
if(head == NULL || root == NULL)
{
return;
}
int i = 0;
printf("主栈:[ ");
for(i = head->size-1;i >= 0;i--)
{
printf("%d ",head->arr[i]);
}
printf("]\n");
printf("最小栈:[ ");
for(i = root->size-1;i >= 0;i--)
{
printf("%d ",root->arr[i]);
}
printf("]\n");
}
void testminstack()
{
LINE;
stack head;
stackInit(&head);
stack root;
stackInit(&root);
printf("Push:\n");
stackPush(&head,&root,9);
stackprint(&head,&root);
printf("取当前最小栈的栈顶值:%d\n",getmin(&root));
printf("\n");
stackPush(&head,&root,5);
stackprint(&head,&root);
printf("取当前最小栈的栈顶值:%d\n",getmin(&root));
printf("\n");
stackPush(&head,&root,2);
stackprint(&head,&root);
printf("取当前最小栈的栈顶值:%d\n",getmin(&root));
printf("\n");
stackPush(&head,&root,7);
stackprint(&head,&root);
printf("取当前最小栈的栈顶值:%d\n",getmin(&root));
printf("Pop:\n");
stackprint(&head,&root);
printf("取当前最小栈的栈顶值:%d\n",getmin(&root));
stackPop(&head,&root);
printf("\n");
stackprint(&head,&root);
printf("取当前最小栈的栈顶值:%d\n",getmin(&root));
stackPop(&head,&root);
printf("\n");
stackprint(&head,&root);
printf("取当前最小栈的栈顶值:%d\n",getmin(&root));
stackPop(&head,&root);
printf("\n");
stackprint(&head,&root);
printf("取当前最小栈的栈顶值:%d\n",getmin(&root));
stackPop(&head,&root);
}
int main()
{
testminstack();
return 0;
}