常数时间内检索到栈中的最小元素

1.借助辅助栈
         原栈正常压栈,原栈每进入一个元素,辅助栈这里就要判断,当原栈进入第一个元素时,辅助栈也将这个元素入栈,当原栈进入第二个元素时,辅助栈就要将这个元素与栈顶元素进行比较,若此元素比栈顶元素小,则直接进栈,若此元素比栈顶元素大,则不进辅助栈,这样辅助栈的栈顶元素就是原栈里最小的那个元素
2.不借助辅助栈,单栈完成检索
       入栈:
         不借助辅助栈,就在一个栈内完成检索操作,每次入栈两个元素,一个是入栈元素本身,一个是当前栈元素的最小值,当栈为空时,直接入栈,且将这个元素入栈两次,当栈不为空时,先保存当前栈的最小值min,再将要压栈的元素(val)入栈,如果min<val则,再将min入栈,如果min>val,则再将val进栈,因为每次要保证入栈两个元素。
       出栈:
         按照每次进栈两个元素看来,每次进栈的第一个元素是本来就要进栈的,第二个元素是栈中最小元素,所以,此时栈顶元素是栈中的倒数第二个元素,最小值是栈中的倒数第一个元素。所以如果要出栈的话,一次性也要出两个元素。
力扣155单栈实现最小值检索代码如下:

#define MAXSIZE 1600

typedef struct {
    int *data;
    int top;
} MinStack;


/** initialize your data structure here. */

MinStack* minStackCreate() {
    MinStack *stack;
    stack=(MinStack*)malloc(sizeof(MinStack));
    stack->data=(int *)malloc(MAXSIZE*sizeof(int));
    stack->top=-1;
    return stack; 
}

void minStackPush(MinStack* obj, int val) {
    if(obj->top==MAXSIZE-1) {//如果栈满,就返回空

    }
    else if(obj->top==-1) {//如果栈空,直接进栈,每次入栈两个元素,一个是入栈元素本身,一个是当前栈元素的最小值
        obj->top++;
        obj->data[obj->top]=val;
        obj->top++;
        obj->data[obj->top]=val;
    }
    else {//如果栈不空,就要与栈顶元素作比较
        int temp=obj->data[obj->top];//先记录此时栈顶元素
        obj->top++;//再将要压入栈的元素进栈
        obj->data[obj->top]=val;
        if(temp<val) {//如果原来栈顶元素小于要压栈的元素
            obj->top++;
            obj->data[obj->top]=temp;//就把它放在栈顶
        }
        else {//否则就把要压栈的元素放在栈顶
            obj->top++;
            obj->data[obj->top]=val;
        }
    }

}

void minStackPop(MinStack* obj) {
   if(obj->top==-1) {//如果是空栈

   }
   else {//入栈是两个入,出栈也是两个出
       obj->top--;
       obj->top--;
   }
}

int minStackTop(MinStack* obj) {
   if(obj->top==-1) {
       return -1;
   }
   return obj->data[obj->top-1];
}

int minStackGetMin(MinStack* obj) {
    return obj->data[obj->top];
}

void minStackFree(MinStack* obj) {
    free(obj->data);
    obj->data=NULL;
    free(obj);
    obj=NULL;
}


借助辅助栈实现常数检索代码如下:

#include<stdio.h>
typedef struct node {
	int data[100];
	int index;
}Node;


//对栈进行初始化操作其实就是初始化栈顶指针
void init(Node *s) {
	s->index = -1;
}

void push(Node *s) {
	int n;
	while (1) {
		scanf_s("%d", &n);
		if (n == 0)
			break;
		(*s).index++;
		(*s).data[(*s).index] = n;
	}
}

int peek(Node s) {
	return s.data[s.index];
}

void pop(Node* s,int *e) {
	*e = (*s).data[(*s).index];
	(*s).index--;
}

void q(Node* p,Node *s) {//p就是辅助栈
	int i;
	for (i = 0; i <= (*s).index; i++) {
		if (p->index == -1) {//如果辅助栈是空,直接进栈 
			p->index++;
			p->data[p->index] = s->data[i];
		}
		else {//如果不是空,就要进行比较
			if (s->data[i] < p->data[p->index]) {//要压栈的元素比栈中最小的值小才压栈,否则不进栈
				p->index++;
				p->data[p->index] = s->data[i];
			}
		}
	}
}

int main(void) {
	Node s,m;
	init(&m);
	init(&s);
	push(&s);
	int e;
	q(&m, &s);
	pop(&m, &e);
	printf("%d", e);
	return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值