设计包含 min 函数的栈

题目:

定义栈的数据结构,要求添加一个 min 函数,能够得到栈的最小元素。要求函数 min、push 以及pop 的时间复杂度都是 O(1).


程序执行之后的结果:

程序执行结果

#ifndef STACK_H_INCLUDED
#define STACK_H_INCLUDED

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

#define STACK_INIT_SIZE 50
#define STACK_INCREMNET 20

#define SElemType int

typedef struct min_stack{
	int * top;
	int * base;
	int stacksize;
}min_stack;

typedef struct seq_stack{
	SElemType * top;
	SElemType * base;
	int stacksize;
	min_stack *min;
}stack;

int init_stack(stack *s);
int destroy_stack(stack *s);
int clear_stack(stack *s);

int getlen(stack s);
int is_empty(stack s);
int is_full(stack s);

int get_top(stack s,SElemType *e);
int push(stack *s,SElemType n);
int pop(stack *s,SElemType *n);
int get_min(stack *s, SElemType *n);

int stack_traverse(stack s);

#endif

#include "stack.h"

int init_stack(stack *s){
    s->base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
    if(!s->base)
    	return 1;
    s->top=s->base;
    s->stacksize=STACK_INIT_SIZE;

    s->min=(min_stack *)malloc(sizeof(min_stack));
    s->min->base=(int *)malloc(STACK_INIT_SIZE*sizeof(int));
    if(!s->min->base)
    	return 1;
    s->min->top=s->min->base;
    s->min->stacksize=STACK_INIT_SIZE;

    printf("\nA new stack with min stack has been established!\n");
    return 0;
}

int destroy_stack(stack *s){
    if(!s)
        return 0;
    if(s->min){
        free(s->min->base);
        free(s->min);
        s->min=NULL;
    }
    free(s->base);
    s->base=s->top=NULL;
    s->stacksize=0;
    printf("\nThe stack has been destroyed!\n");
    return 0;
}
int clear_stack(stack *s){
    if(!s)
        return 0;
    s->top=s->base;
    s->min->top=s->min->base;
    return 0;
}

int getlen(stack s){
	return (s.top-s.base);
}
int is_empty(stack s){
	return s.base==s.top;
}
int is_full(stack s){
	return (s.top-s.base==s.stacksize);
}

int get_top(stack s,SElemType *e){
    if(s.base==s.top)
        return 0;
    *e=*(s.top-1);
    return 0;
}

/*
 * 下面这三个函数的实现才是该题目的重点!
 * */

int push(stack *s,SElemType n){
	int min_index=-1;
	if(s->min->top != s->min->base){
		min_index= *(s->min->top-1);
	}

    if(s->top-s->base>=s->stacksize)
    {
        s->base=(SElemType *)realloc(s->base,sizeof(SElemType)*(s->stacksize+STACK_INCREMNET));
        if(!s->base)
            return 0;
        s->top=s->base+s->stacksize;
        s->stacksize+=STACK_INCREMNET;
    }
    if(s->min->top-s->min->base>=s->min->stacksize)
    {
        s->min->base=(int *)realloc(s->min->base,sizeof(int)*(s->min->stacksize+STACK_INCREMNET));
        if(!s->min->base)
            return 0;
        s->min->top=s->min->base+s->min->stacksize;
        s->min->stacksize+=STACK_INCREMNET;
    }

	*s->top++=n;
	/* 如果2个数相等且都是最小值,则取先进栈的为最小值 */
	if(min_index== -1){
		*s->min->top++=0;
	}else if(*(s->base+min_index)>n)
		*s->min->top++=(s->top-s->base-1);

	return 0;
}
/*
 * @指针n指向的内存位置存储栈中的退栈元素
 * */
int pop(stack *s,SElemType *n){
	int min_index=-1;

    if(s->base==s->top)
        return 0;
	if(s->min->top != s->min->base){
		min_index= *(s->min->top-1);
	}else
		return 1;

    if(s->top-s->base-1 == min_index){
    	s->min->top--;
    }
	*n= *(--s->top);
	return 0;
}
/*
 * @指针n指向的内存位置存储栈中的最小值
 * @返回最小值的索引
 * */
int get_min(stack *s, SElemType *n){
	int min_index=-1;
	if(s->min->top != s->min->base){
		min_index= *(s->min->top-1);
	}
	*n=*(s->base+min_index);
	return min_index;
}
/*
 * 按进栈顺序输出
 * */
int stack_traverse(stack s){
    SElemType* e;
    int *min,i=0;
    if(s.top==s.base){
       printf("This stack is empty!");
       return 0;
    }

    e=s.base;
    min=s.min->base;

    printf("栈中元素按进栈顺序依次为:\n");
    for(;e<s.top;e++,i++){
         printf("%d\t",*e);
         if(i%6==5)
            printf("\n");
    }
    i=0;
    printf("\n栈中最小元素序号依次为:\n");
    for(;min<s.min->top;min++,i++){
         printf("%d\t",*min);
         if(i%6==5)
            printf("\n");
    }
    return 0;
}

测试Stack:

/*
 * main.c
 *
 *  Created on: Dec 3, 2013
 *      Author: bing
 *
 *  test sequence stack
 */

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

int main()
{
    stack s;
    SElemType i,p;

    init_stack(&s);
    for(i=20;i>10;i--)
        push(&s,i);
    for(i=1;i<=10;i++)
        push(&s,i);
    stack_traverse(s);
printf("\n开始退栈....\n");
    for(i=15;i>0;i--)
        pop(&s,&p);
    stack_traverse(s);

    destroy_stack(&s);

    return 0;
}

编码水平太差,不对的地方请指正!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值