当前位置: 首页>>数据结构>>正文


可以求最小值的栈的实现(C语言)(原创)

问题:实现一个栈,要求含有函数push, pop, min,并且他们的时间复杂度都是O(1)。

解决思路:如图1所示,在普通栈的基础上,增加当前最小节点的指针currentMinNode,以及指向下一个最小节点的指针

nextMinNode。当push元素到栈里面时,如果新元素小于栈中的currentMinNode,需要更新当前最小元素指针currentMinNode,

使它指向新元素;如果新元素不小于currentMinNode,和普通栈一样直接添加新节点。当从栈中POP元素时,如果当前栈顶

节点的nextMinNode为空,则和普通栈一样直接删除栈顶节点;如果当前栈顶节点的nextMinNode不为空,则更新currentMinNode

指向栈顶节点的nextMinNode,然后再删除栈顶节点。本文主要说明求栈中最小值的情形,实际上,这里的处理思路可以很方便的迁移到求栈中最大值的情形。

3

图1 含有MIN函数的栈的结构

           含有MIN函数的栈的C语言实现源码如下,这里栈中可存储的数据是简单的INT类型。


/*
* File: stack.h
* Purpose: implementation of stack which having MIN function in c
* Author: puresky
*/

#ifndef _STACK_H
#define _STACK_H

typedef struct StackNodeStruct StackNode;
struct StackNodeStruct
{
        int _data;
        struct StackNodeStruct *_next;
        struct StackNodeStruct *_nextMinNode;
};

typedef struct StackStruct Stack;
struct StackStruct
{
        StackNode *_top;
        StackNode *_currentMinNode;
        int _count;
};

Stack *stack_new();
void stack_free(Stack *st);
void stack_push(Stack *st, int data);
int stack_top(Stack *st);
int stack_pop(Stack *st);
int stack_min(Stack *st);
int stack_size(Stack *st);
int stack_empty(Stack *st);
void stack_print(Stack *st);
#endif

/*
 * File: stack.c
 * Purpose: implementation of stack in c
 * Author: puresky
 */
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"

StackNode *stack_node_new(int data)
{
        StackNode *stn = (StackNode *)malloc(sizeof(StackNode));
        stn->_data = data;
        stn->_next = NULL;
        stn->_nextMinNode = NULL;
        return stn;
}
void stack_node_free(StackNode *stn)
{
        if(stn)
        {
                free(stn);
        }
}

Stack *stack_new()
{
        Stack *st = (Stack *)malloc(sizeof(Stack));
        st->_count = 0;
        st->_top = NULL;
        st->_currentMinNode = NULL;
        return st;
}
void stack_free(Stack *st)
{
        StackNode *stn;
        StackNode *iter;
        if(st)
        {
                iter = st->_top;
                while(iter)
                {
                        stn = iter;
                        iter = iter->_next;
                        stack_node_free(stn);
                }
        }
}

void stack_push(Stack *st, int data)
{
        StackNode *stn = stack_node_new(data);
        stn->_next = st->_top;
        st->_top = stn;
        st->_count++;
        if(st->_currentMinNode == NULL)
        {
                st->_currentMinNode = stn;
        }
        else if(stn->_data < st->_currentMinNode->_data)
        {
                stn->_nextMinNode = st->_currentMinNode;
                st->_currentMinNode = stn;
        }
        else
        {
                stn->_nextMinNode = NULL;
        }
        printf("push %d\n", data);
}

int stack_top(Stack *st)
{
        if(st->_top)
        {
                return st->_top->_data;
        }
        fprintf(stderr, "top error : stack is empty!\n");
        return -1;
}

int stack_pop(Stack *st)
{
        int ret;
        StackNode *stn;
        if(st->_top)
        {
                if(st->_top->_nextMinNode)
                {
                        st->_currentMinNode = st->_top->_nextMinNode;
                }
                ret = st->_top->_data;
                stn = st->_top;
                st->_top = st->_top->_next;
                stack_node_free(stn);
                st->_count--;
                printf("pop %d\n", ret);
                return ret;
        }
       
        fprintf(stderr, "pop error : stack is empty!\n");
       
        return -1;
}

int stack_min(Stack *st)
{
        if(st->_top)
        {
                return st->_currentMinNode->_data;
        }
        fprintf(stderr, "min error : stack is emtpy!\n");
        return -1;
}

int stack_size(Stack *st)
{
        return st->_count;
}

int stack_empty(Stack *st)
{
        if(st->_top == NULL)
                return 1;
        return 0;
}

void stack_print(Stack *st)
{
        StackNode *ptr = st->_top;
        printf("--------------------------------------------------\n");
        printf("stack size:%d\n", st->_count);
        printf("stack min:%d\n", st->_currentMinNode->_data);
        while(ptr)
        {
                printf("%d ", ptr->_data);
                ptr = ptr->_next;
        }
        printf("\n--------------------------------------------------\n\n");
}

/*
 * File: main.c
 * Purpose: To test the stack
 * Author: puresky
 */

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

#define MAX_NUM 20
#define N 10

void init_stack(Stack *st, int size)
{
        int i, j;
        for(i = 0; i < size; ++i)
        {
                j = rand() %  MAX_NUM;
                stack_push(st, j);
        }
}

int main(int argc, char **argv)
{
        Stack *st = stack_new();

        srand(time(NULL));
        init_stack(st, N);
        stack_print(st);
        stack_pop(st);
        stack_pop(st);
        stack_pop(st);
        stack_pop(st);
        stack_pop(st);


        stack_print(st);

        stack_free(st);
        system("pause");
        return 0;
}
本文由《纯净天空》出品。文章地址: https://vimsky.com/article/52.html,未经允许,请勿转载。