包含min函数的栈

【题目】
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的的min函数。在该栈中,调用min\push\pop的时间复杂度都为O(1)。


【分析】
对于本题,如果想要在实时得到栈中数据的最小值,对栈内排序或者遍历查找时间复杂度都很大,所以保证时间复杂度的情况下找到最小元素的办法就是设立一个辅助栈,一直存放数据最小值,在压入栈的同时,与辅助栈栈顶对比,如果辅助栈栈顶元素小于压入栈元素,则辅助栈压入与原栈顶一样大小的元素,否则,将入栈元素同时也压入辅助栈中,保持栈顶一直为数据栈中最小值,具体过程详见下图:

这里写图片描述

如上图所示,存在两个栈,数据栈和辅助栈,压入3,两栈皆为空,所以此时3为最小,压入两栈,压入4,比较4与辅助栈栈顶元素3,3小,所以将4压入数据栈,将3压入辅助栈,以此方式压栈,出栈时,最顶元素1出栈,出栈的同时,辅助栈也要出栈,保持数据个数一致,此时数据栈中最小元素就是辅助栈中的栈顶元素,是2。


【测试代码】
“stack.h”

#define OK 1
#define ERROR 0
typedef int Status;
typedef int ElemType;

//节点类型
typedef struct node{
    int m_value;
    struct node* next;
}Node;

typedef struct{
    Node *top;   //栈顶指针
    Node *pmin; //指向栈中最小的值
    unsigned int stacksize; //栈的大小
}stack;

Status initStack(stack *s);
Status push(stack *s, ElemType *e);
Status pop(stack *s,ElemType *e);
Status getTop(stack *s,ElemType *e);
bool stackEmpty(stack *s);
Status min(stack *s,ElemType *e);

“stack.cpp”

#include<stdio.h>
#include"stack.h"
#include<stdlib.h>

//初始化栈的信息
Status initStack(stack *s)
{
    s->top = NULL;
    s->pmin = NULL;
    s->stacksize = 0;

    return OK;
}
//判断是否为空栈
bool stackEmpty(stack *s)
{
    return (s->top == NULL);
}
//入栈操作
Status push(stack *s, ElemType *e)
{
    Node *pNode = (Node *)malloc(sizeof(Node));
    pNode->m_value = *e;
    pNode->next = NULL;
    //开始的时候数据栈为空
    if(stackEmpty(s))
    {
        s->top = pNode;
        s->pmin = s->top;
        s->stacksize += 1;
    }
    //数据栈不为空时
    else
    {       
            //前插法_数据栈添加新元素
            pNode->next = s->top;
            s->top = pNode;
            s->stacksize += 1;
            //辅助栈添加最小值
            Node *ptmp_min = (Node *)malloc(sizeof(Node));
            ptmp_min->m_value = s->pmin->m_value;
            ptmp_min->next = s->pmin;

            if(s->pmin->m_value > *e)
                ptmp_min->m_value = *e;

            s->pmin = ptmp_min;
            s->stacksize ++;    
    }
    return OK;
}
//出栈操作
Status pop(stack *s,ElemType *e)
{
    //栈不为空
    if(!stackEmpty(s))
    {
        //数据栈出栈
        Node* pNode = s->top;
        *e = s->top->m_value;
        s->top = s->top->next;
        free (pNode);
        //辅助栈相应出栈
        Node * pTemp = s->pmin;
        s->pmin = s->pmin->next;
        free (pTemp);

        return OK;
    }
    return ERROR;
}
//取栈顶元素
Status getTop(stack *s,ElemType *e)
{
    //栈不为空
    if(!stackEmpty(s))
    {
        (*e) = s->top->m_value;
        return OK;
    }

    return ERROR;
}
//最小值
Status min(stack *s,ElemType *e)
{
    if(!stackEmpty(s))
    {
        *e = s->pmin->m_value;
        return OK;
    }

    return ERROR;
}

“main.cpp”

#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
int main()
{
    int in[] = {3,4,2,1};

    ElemType *e =(ElemType *)malloc(sizeof(ElemType)) ;

    stack *s = (stack *)malloc(sizeof(stack));
    initStack(s);

    for(int i = 0 ; i< 4; i++)
        push(s,&in[i]);

    if(getTop(s,e))
    {
        printf("The top of the stack is %d\n",*e);
    }
    else
    {
        printf("取栈顶出错误!\n");
        exit(0);
    }
    min(s,e);
    printf("栈的最小值为: %d\n",*e);

    pop(s,e);

    min(s,e);
    printf("栈顶出栈后,栈的最小值为: %d\n",*e);

    pop(s,e);

    min(s,e);
    printf("栈顶出栈后,栈的最小值为: %d\n",*e);

    int number = 0;
    push(s,&number);
    min(s,e);
    printf("栈顶出栈后,栈的最小值为: %d\n",*e);

    return 0;
}

【输出】
这里写图片描述


【参考文档】
http://blog.sina.com.cn/s/blog_60c8379d01013pup.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值