题目:
定义栈的数据结构,要求添加一个 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;
}
编码水平太差,不对的地方请指正!