最小栈

最小栈:有入栈,出栈,取栈顶元素,取出栈内的最小值的时间复杂度均为O(1);

有两种实现方式:

第一种:使用一个栈没入栈一个元素,都再次把最小值插入,所以每次入栈,其实要入两个元素,栈顶永远是最小值,取栈内最小值就是取栈顶元素,将9725入栈,出栈,取栈顶元素如下图:

入栈过程:

出栈:


取栈顶元素:


代码如下:

头文件MinStack1.h

#pragma once

#define MinStackMaxSize 1000

#define MinStackType char

typedef struct MinStack {
    MinStackType data[MinStackMaxSize];
    size_t size;
}MinStack;

void MinStackInit(MinStack* minstack);   //初始化栈

void MinStackPush(MinStack* minstack, MinStackType value); //入栈

void MinStackPop(MinStack* minstack);   //出栈

int MinStackTop(MinStack* minstack, MinStackType* min_value);   //取栈顶元素

头文件的实现Minstack1.c

#include<stdio.h>
#include"MinStack1.h"

void MinStackInit(MinStack* minstack) {
    if(minstack == NULL) {
        return;
    }
    minstack->size = 0;
    return;
}

void MinStackPush(MinStack* minstack, MinStackType value) {
    if(minstack == NULL || minstack->size >= MinStackMaxSize) {
        return;
    }
    if(minstack->size == 0) {
        minstack->data[minstack->size] = value;    
        minstack->size++;
        minstack->data[minstack->size] = value;    
        minstack->size++;
        return;
    }
    MinStackType min;
    min = minstack->data[minstack->size - 1] > value ? value : minstack->data[minstack->size - 1];
    minstack->data[minstack->size] = value;    
    minstack->size++;
    minstack->data[minstack->size] = min;    
    minstack->size++;
    return;
}

void MinStackPop(MinStack* minstack) {
    if(minstack == NULL || minstack->size == 0) {
        return;
    }
    minstack->size -= 2;
}

int MinStackTop(MinStack* minstack, MinStackType* min_value) {
    if(minstack == NULL || min_value == NULL) {
        return 0;
    }
    if(minstack->size == 0) {
        return 0;
    }
    *min_value = minstack->data[minstack->size - 1];
    return 1;
}

/////////////////////////////////////////////////////////////////
//以下为测试代码
//////////////////////////////////////////////////////////////////
MinStack minstack;
void TestMinStack() {
    MinStackInit(&minstack);
    MinStackPush(&minstack, '9');
    MinStackPush(&minstack, '5');
    MinStackPush(&minstack, '7');
    MinStackPush(&minstack, '2');
    
    MinStackType top;
    int ret;
    ret = MinStackTop(&minstack, &top);
    printf("ret expected 1, actual %d\n", ret);
    printf("top expected 2, actual %c\n", top);
    MinStackPop(&minstack);

    ret = MinStackTop(&minstack, &top);
    printf("ret expected 1, actual %d\n", ret);
    printf("top expected 5, actual %c\n", top);
    MinStackPop(&minstack);
    
    ret = MinStackTop(&minstack, &top);
    printf("ret expected 1, actual %d\n", ret);
    printf("top expected 5, actual %c\n", top);
    MinStackPop(&minstack);
    
    ret = MinStackTop(&minstack, &top);
    printf("ret expected 1, actual %d\n", ret);
    printf("top expected 9, actual %c\n", top);
    MinStackPop(&minstack);
    
    ret = MinStackTop(&minstack, &top);
    printf("ret expected 0, actual %d\n", ret);
    MinStackPop(&minstack);
}

int main()
{
    TestMinStack();

    return 0;
}

实验结果:


缺点:虽然符合最小栈的要求,但是却只能得到栈中的最小值,却不能得到真正入栈的栈顶元素


第二种:使用两个栈,stack 和 min_stack , stack存放真正入栈的元素, min_stack存放stack的最小元素,所以min_stack的栈顶总是当前stack中的最小值,原理如下图:

入栈:


出栈:


取栈顶元素:


代码如下:

头文件:MinStack2.h

#pragma once

#define MinStackMaxSize 1000

#define MinStackType char

typedef struct MinStack {
    MinStackType data[MinStackMaxSize];
    size_t size;
}MinStack;

typedef struct MinStackByTwo {
    MinStack stack;
    MinStack min_stack;
}MinStackByTwo;

void MinStackInit(MinStackByTwo* minstack_bytwo);    //栈的初始化

void MinStackPush(MinStackByTwo* minstack_bytwo, MinStackType value);   //入栈

void MinStackPop(MinStackByTwo* minstack_bytwo); //出栈

int MinStackTop(MinStackByTwo* minstack_bytwo, MinStackType* top, MinStackType* min_value); //取栈顶元素

头文件的实现:MinStack2.c

#include<stdio.h>
#include"MinStack2.h"

void MinStackInit(MinStackByTwo* minstack_bytwo) {
    if(minstack_bytwo == NULL) {
        return;
    }
    minstack_bytwo->stack.size = 0;
    minstack_bytwo->min_stack.size = 0;
    return;
}

void MinStackPush(MinStackByTwo* minstack_bytwo, MinStackType value) {
    if(minstack_bytwo == NULL || minstack_bytwo->stack.size >= MinStackMaxSize) {
        return;
    }
    if(minstack_bytwo->stack.size == 0) {
        minstack_bytwo->stack.data[minstack_bytwo->stack.size] = value;    
        minstack_bytwo->stack.size++;
        minstack_bytwo->min_stack.data[minstack_bytwo->min_stack.size] = value;    
        minstack_bytwo->min_stack.size++;
        return;
    }
    MinStackType min = value;
    if(value >= minstack_bytwo->min_stack.data[minstack_bytwo->min_stack.size - 1]) {
        min = minstack_bytwo->min_stack.data[minstack_bytwo->min_stack.size - 1];
    }
    minstack_bytwo->stack.data[minstack_bytwo->stack.size++] = value;    
    minstack_bytwo->min_stack.data[minstack_bytwo->min_stack.size++] = min;    
    return;
}

void MinStackPop(MinStackByTwo* minstack_bytwo) {
    if(minstack_bytwo == NULL || minstack_bytwo->stack.size == 0) {
        return;
    }
    minstack_bytwo->stack.size -= 1;
    minstack_bytwo->min_stack.size -= 1;
    return;
}

int MinStackTop(MinStackByTwo* minstack_bytwo,MinStackType* top_value, MinStackType* min_value) {
    if(minstack_bytwo == NULL || min_value == NULL) {
        return 0;
    }
    if(minstack_bytwo->stack.size == 0) {
        return 0;
    }
    *min_value = minstack_bytwo->min_stack.data[minstack_bytwo->min_stack.size - 1];
    *top_value = minstack_bytwo->stack.data[minstack_bytwo->stack.size - 1];
    return 1;
}


/////////////////////////////////////////////////////////////////
//以下为测试代码
//////////////////////////////////////////////////////////////////

void TestMinStackByTwo() {
    MinStackByTwo minstack;
    MinStackInit(&minstack);
    MinStackPush(&minstack, '9');
    MinStackPush(&minstack, '5');
    MinStackPush(&minstack, '7');
    MinStackPush(&minstack, '2');

    MinStackType min;
    MinStackType top;
    int ret;
    ret = MinStackTop(&minstack, &top, &min);
    printf("ret expected 1, actual %d\n", ret);
    printf("top expected 2, actual %c\n", top);
    printf("min expected 2, actual %c\n", min);
    MinStackPop(&minstack);

    ret = MinStackTop(&minstack, &top, &min);
    printf("ret expected 1, actual %d\n", ret);
    printf("top expected 7, actual %c\n", top);
    printf("min expected 5, actual %c\n", min);
    MinStackPop(&minstack);
    
    ret = MinStackTop(&minstack, &top, &min);
    printf("ret expected 1, actual %d\n", ret);
    printf("top expected 5, actual %c\n", top);
    printf("min expected 5, actual %c\n", min);
    MinStackPop(&minstack);
    
    ret = MinStackTop(&minstack, &top, &min);
    printf("ret expected 1, actual %d\n", ret);
    printf("top expected 9, actual %c\n", top);
    printf("min expected 9, actual %c\n", min);
    MinStackPop(&minstack);

    ret = MinStackTop(&minstack, &top, &min);
    printf("ret expected 0, actual %d\n", ret);
    MinStackPop(&minstack);
}


int main()
{
    TestMinStackByTwo();

    return 0;
}

实验结果:


阅读更多
个人分类: c语言 数据结构
上一篇环境变量
下一篇用fock实现简易shell(程序替换)
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭