1 题目描述
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数,在该栈中,调用 min、push及pop 的时间复杂度是 O(1)。
2 解法描述
常规想法
- 往栈里添加一个成员变量保存最小的元素,每次压入一个元素的时候比较待压入元素与当前最小元素的大小,如果该元素比当前最小元素小,更新最小元素。(不可行,如果当前最小元素出栈,无法在 O(1)时间内找到下一个最小元素)。
本题解法
数据结构
typedef struct node1{
Stack dataStack;
Stack minStack;
}newStackNode,*NStack;
上图是栈进行 push 操作后,dataStack 和 minStack 栈的内容,两个栈中元素个数是相等的,对应位置的数字代表了如下含义:
当 dataStack 栈中元素 a 未出栈时,minStack 中对应位置元素 a1 代表了此时 dataStack 中最小的元素。
3 C语言实现
#include<stdio.h>
typedef int ElemType;
typedef struct node{
ElemType data;
struct node *next;
}SNode,*Stack;
typedef struct node1{
Stack dataStack;
Stack minStack;
}newStackNode,*NStack;
//初始化栈的头结点
void initStack(Stack* stack){
(*stack)=(SNode*)malloc(sizeof(SNode));
(*stack)->data=0;
(*stack)->next=NULL;
}
//所有操作都在表头进行,头插法
int _push(Stack stack,ElemType data){
SNode *push;
//如果Stack尚未初始化
if(stack==NULL) return 0;
push=(SNode*)malloc(sizeof(SNode));
push->data=data;
push->next=stack->next;
stack->next=push;
}
//出栈
int _pop(Stack stack,ElemType* popVlaue){
//如果Stack为空
if(isEmpty(stack)) return 0;
SNode *pop=stack->next;
*popVlaue=pop->data;
stack->next=pop->next;
free(pop);
return 1;
}
//获得栈顶元素
int getTop(Stack stack,ElemType* topVlaue){
//如果Stack为空
if(isEmpty(stack)) return 0;
*topVlaue=stack->next->data;
return 1;
}
//判断是否为空
int isEmpty(Stack stack){
return stack!=NULL&&stack->next==NULL?1:0;
}
//遍历Stack当前最小
void showStack(Stack stack){
if(isEmpty(stack)) return;
SNode* temp=stack->next;
printf("----- stack elements:");
while(temp!=NULL){
printf(" %d",temp->data);
temp=temp->next;
}
}
void initNewStack(NStack *newstack){
*newstack=(newStackNode*)malloc(sizeof(newStackNode));
initStack(&((*newstack)->dataStack));
initStack(&((*newstack)->minStack));
}
void push(NStack ns,ElemType data){
ElemType min;
_push(ns->dataStack,data);
if(isEmpty(ns->minStack)){
_push(ns->minStack,data);
}else{
getTop(ns->minStack,&min);
if(min<=data){
_push(ns->minStack,min);
}else{
_push(ns->minStack,data);
}
}
}
int pop(NStack ns,ElemType* popVlaue){
return (_pop(ns->minStack,popVlaue)&&_pop(ns->dataStack,popVlaue));
}
int min(NStack ns,ElemType* mindata){
return getTop(ns->minStack,mindata);
}
void main(){
NStack ns=NULL;
initNewStack(&ns);
ElemType data=6;
push(ns,data);
data=2;
push(ns,data);
data=3;
push(ns,data);
data=4;
push(ns,data);
data=5;
push(ns,data);
data=1;
push(ns,data);
pop(ns,&data);
min(ns,&data);
printf("min=%d",data);
printf("\n");
showStack(ns->dataStack);
printf("\n");
showStack(ns->minStack);
}