栈的扩展——最小栈

最小栈和栈的区别就是,在时间复杂度为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;
}

猜你喜欢

转载自blog.csdn.net/q496958148/article/details/80145547