1.实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值)的时间 复杂度为O(1)
创建2个栈 s 和 min ,入栈时,先入栈s,在判断是否<=栈min的top元素,如果是,则同时也入min栈,否则不入。
出栈时,如果s栈的top元素与min栈的top元素相等,则两个都出栈,否则只出s栈的top取min值时直接返回min栈top元素即可
function.h
#pragma once
#include"stack.h"
void minstack_push(Stack *s, Stack *min, DataType x)
{
assert(s);
assert(min);
StackPush(s, x);
if (min->_top == 0 || StackTop(min) >= x)
{
StackPush(min,x);
}
}
void minstack_pop(Stack *s, Stack *min)
{
assert(s);
assert(min);
if (StackTop(s) == StackTop(min))
{
StackPop(min);
}
StackPop(s);
}
int minstack_min(Stack *min)
{
assert(min);
return StackTop(min);
}
2.使用两个栈实现一个队列
思路:创建两个栈s1和s2,
当要入数据时,只往s1当中入数据,
需要出数据时,先看s2里是否有元素,如果有,则先出s2内的数据,如果s2为空,则先将s1的数据依次导到s2中,再出数据。
function.h
#pragma once
#include"stack.h"
void double_stack_to_queue_push(Stack *s1,DataType x)
{
assert(s1);
StackPush(s1,x);
}
void double_stack_to_queue_pop(Stack *s1, Stack *s2)
{
assert(s1);
assert(s2);
if (StackEmpty(s2) == 0)
{
printf("%d\t", StackTop(s2));
StackPop(s2);
return;
}
else
{
if (StackEmpty(s1) == 1)
{
printf("两个栈均无数据,无法出栈!");
return;
}
while (StackEmpty(s1) == 0)
{
StackPush(s2, StackTop(s1));
StackPop(s1);
}
printf("%d\t", StackTop(s2));
StackPop(s2);
}
}
3使用两个队列实现一个栈
思路:创建2个队列 q1和q2,
入数据时,如果两个队列都为空,则往q1入数据,如果q1和q2中有一个为空,一个不为空,则往不为空的那个队列入数据(即一直保持一个队列为空)
当要出数据时,将不为空的队列中的n-1个数据挪至为空的队列,这时候原本不为空的队列中只剩一个数据且是最后入的数据,pop掉即可。(仍然保持一个队列为空)
functions.h
#pragma once
#include"queue.h"
void double_queue_to_stack_push(Queue *q1, Queue *q2, DataType x)
{
if (QueueEmpty(q1) == 0 && QueueEmpty(q2) == 0)//两个队列都空
{
QueuePush(q1, x);
}
else if (QueueEmpty(q1) == 0)//往不为空的那个队列入数据
{
QueuePush(q2, x);
}
else
{
QueuePush(q1, x);
}
}
void double_queue_to_stack_pop(Queue *q1, Queue *q2)
{
assert(q1);
assert(q2);
if (QueueEmpty(q1) == 0 && QueueEmpty(q2) == 0)
{
printf("两个队列均无数据!");
return;
}
else if (QueueEmpty(q1) == 0)
{
size_t size2 = QueueSize(q2);
while (size2 != 1)
{
QueuePush(q1, QueueFront(q2));
QueuePop(q2);
size2--;
}
printf("%d", QueueFront(q2));
QueuePop(q2);
q2->_tail = q2->_head;
}
else
{
size_t size1 = QueueSize(q1);
while (size1 != 1)
{
QueuePush(q2, QueueFront(q1));
QueuePop(q1);
size1--;
}
printf("%d", QueueFront(q1));
QueuePop(q1);
q1->_tail = q1->_head;
}
}
4.元素出栈、入栈顺序的合法性。如入栈的序列(1,2,3,4,5),出栈序列为 (4,5,3,2,1)
思路:给定入栈序列与出栈序列,用2个指针分别指向他们。
如果指针所指内容相等,说明入栈后立刻出栈,两个指针都后移.
当指针所指内容不相等时,说明入栈序列的值可能暂时存在栈中,稍后会出栈,故对入栈指针进行后移操作,出栈指针不变。
等到入栈序列指针指向NULL后,说明此时要么出栈指针也为空,要么剩余出栈序列与栈内元素一 一匹配才合法。否则不合法。
#include <stdio.h>
#include <stdlib.h>
#define MaxSize 60
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int ElemType;
typedef int Status;
typedef struct {
ElemType data[MaxSize];
int top1;
int top2;
}Stack, *pStack;
Status init_Stack(pStack S)
{
S->top1 = -1;
S->top2 = MaxSize;
return OK;
}
Status push_Stack(pStack S, ElemType e, int stackNumber)
{
if (S->top1+1 == S->top2)
return ERROR;
switch(stackNumber)
{
case 1:
S->data[++S->top1] = e;
break;
case 2:
S->data[--S->top2] = e;
break;
}
return OK;
}
Status pop_Stack(pStack S, ElemType *e, int stackNumber)
{
if (1 == stackNumber)
{
if (-1 == S->top1)
return ERROR;
*e = S->data[S->top1--];
}
else if (2 == stackNumber)
{
if (MaxSize == S->top2)
return ERROR;
*e = S->data[S->top2++];
}
return OK;
}
Status dis_pStack(pStack S, int stackNumber)
{
int i;
if (1 == stackNumber)
{
if (-1 == S->top1)
return ERROR;
printf("栈1中的元素为:\n");
for (i=0; i<=S->top1; ++i)
printf("%d ", S->data[i]);
printf("\n==================================\n");
}
else if (2 == stackNumber)
{
if (MaxSize == S->top2)
return ERROR;
printf("栈2中的元素为:\n");
for (i=MaxSize-1; i>=S->top2; --i)
printf("%d ", S->data[i]);
printf("\n==================================\n");
}
}
int main()
{
printf("======共享栈===========\n\n");
Stack S;
ElemType e;
init_Stack(&S);
push_Stack(&S, 1, 1);
push_Stack(&S, 2, 1);
push_Stack(&S, 3, 1);
push_Stack(&S, 4, 1);
push_Stack(&S, 5, 1);
push_Stack(&S, 6, 1);
pop_Stack(&S, &e, 1);
push_Stack(&S, 10, 2);
push_Stack(&S, 9, 2);
push_Stack(&S, 8, 2);
push_Stack(&S, 7, 2);
dis_pStack(&S, 1);
dis_pStack(&S, 2);
return 0;
}