实现一个栈,要求返回最小值
有3种方法,分别为:
- 用一个栈实现,偶数下标存普通数据,奇数下标为最小的值
typedef struct MinStack
{
int array[100];//偶数下标存普通数据,奇数下标为最小的值
int top;
}MinStack;
void Init(MinStack *pS)
{
pS->top = 0;
}
//入栈
void Push(MinStack *pS, int data)
{
assert(pS != NULL);
assert(pS->top < 100);
int min = data;
if (pS->top != 0 && pS->array[pS->top - 1] < data)
{
min = pS->array[pS->top - 1];
}
pS->array[pS->top++] = data;
pS->array[pS->top++] = min;
}
//出栈
void Pop(MinStack *pS)
{
assert(pS);
pS->top -= 2;
}
//最小元素
int Min(MinStack *pS)
{
return pS->array[pS->top - 1];
}
//栈顶元素(普通数据)
int Top(MinStack *pS)
{
return pS->array[pS->top - 2];
}
- 用两个栈实现 ,其中一个栈存普通数据,另一个栈存最小数
typedef struct MinStack
{
int array1[100];//存放普通数据
int top1;
int array2[100];//存放最小数据
int top2;
}MinStack;
void Init(MinStack *pS)
{
pS->top1 = pS->top2 = 0;
}
void Push(MinStack *pS, int data)
{
int min = data;
if (pS->top2 != 0 && pS->array2[pS->top2 - 1] < data)
{
min = pS->array2[pS->top2 - 1];
}
pS->array1[pS->top1++] = data;
pS->array2[pS->top2++] = min;
}
void Pop(MinStack *pS)
{
pS->top1--;
pS->top2--;
}
int Min(MinStack *pS)
{
return pS->array2[pS->top2 - 1];
}
int Top(MinStack *pS)
{
return pS->array1[pS->top1 - 1];
}
- 用两个数组实现,原理与两个栈基本一致,不过不再每次都入最小栈
typedef struct MinStack {
int array1[100]; // 普通数据(黑色)
int top1;
int array2[100]; // 最小数据(红色)
int top2;
} MinStack;
void Init(MinStack *pStack)
{
pStack->top1 = pStack->top2 = 0;
}
void Push(MinStack *pStack, int data)
{
pStack->array1[pStack->top1++] = data;
if (pStack->top2 == 0 || data <= pStack->array2[pStack->top2 - 1]) //当最小数组中没数据或插入的数据小于最小数组的顶元素时,入最小数组{
pStack->array2[pStack->top2++] = data;
}
}
void Pop(MInStack *pStack)
{
if (pStack->array1[pStack->top1 - 1] == pStack->array2[pStack->top2 - 1]) //当最小栈与普通数组中数据相等{
pStack->top2--;//最小数组中出
}
pStack->top1--;//如果不相等,普通数组出
}
用两个栈实现一个队列
思想:定义两个栈p1和p2,先向p1中入栈,然后将从p1中出栈的数据又入到p2中,再直接把数据从p2中弹出,由此就可以实现队列先进先出的功能。
如图:
typedef struct SQueue
{
Stack stack1;//入数据栈
Stack stack2;//出数据栈
}SQueue;
void Init(SQueue *pSQ)
{
Stack *p1, *p2;
p1 = &(pSQ->stack1);
p2 = &(pSQ->stack2);
StackInit(p1);
StackInit(p2);
}
void Push(SQueue *pSQ, SDataType data)
{
Stack *p1, *p2;
p1 = &(pSQ->stack1);
p2 = &(pSQ->stack2);
StackPush(p1,data);//只入第一个栈
}
void Pop(SQueue *pSQ)
{
SDataType data;
Stack *p1, *p2;
p1 = &(pSQ->stack1);
p2 = &(pSQ->stack2);
if (StackIsEmpty(p2))
{
//当p2为空但p1不为空时,将p1中的数据弹出并压入到栈p2中
while (!StackIsEmpty(p1))
{
data = StackTop(p1);
StackPop(p1);
StackPush(p2, data);
}
}
StackPop(p2);//将p2中数据弹出栈
}
用两个队列实现一个栈
实现方法:定义两个队列,
- 入:数据找一个非空的队列入,如果两个都为空,入第一个队列。
- 出:出非空队列的数据到另一个队列中,直到剩下一个数据,直接将该数据弹出,重复该过程,直到最后一个数字被弹出。。
这里我们重点关注一下:
用一个队列实现一个栈
如图:
重复以上过程,直到最后一个数字被弹出。
代码实现:
typedef struct QStack
{
Queue queue;
}QStack;
void Init(QStack *pQS)
{
QueueInit(&(pQS->queue));
}
void Push(QStack *pQS, QDataType data)
{
QueuePush(&(pQS->queue), data);
}
void Pop(QStack *pQS)
{
int i;
QDataType data;
Queue *pQ = &(pQS->queue);
for (i = 1; i < QueueSize(pQ); i++)
{
data = QueueFront(pQ);
QueuePop(pQ);
QueuePush(pQ, data);
}
QueuePop(pQ);
}
//查看队列顶端元素
QDataType Top(QStack *pQS)
{
int i;
QDataType data;
Queue *pQ = &(pQS->queue);
for (i = 1; i < QueueSize(pQ); i++)
{
data = QueueFront(pQ);
QueuePop(pQ);
QueuePush(pQ, data);
}
data = QueueFront(pQ);
QueuePop(pQ);
QueuePush(pQ, data);
return data;
}