栈与队列面试题

1) 实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值)的时间复杂度为O(1) 
2) 使用两个栈实现一个队列 
3) 使用两个队列实现一个栈 
4) 元素出栈、入栈顺序的合法性。如入栈的序列(1,2,3,4,5),出栈序列为 (4,5,3,2,1) 
5) 一个数组实现两个栈(共享栈)


1) 实现一个栈,要求实现Push(出栈)、Pop(入栈)、Min(返回最小值)的时间复杂度为O(1) 
Topic.h

#pragma once 
#include "Stack.h"
typedef struct MinStack
{
Stack st;
Stack minst;
}MinStack, *pMinStack;
void MinStackInit(pMinStack mst);
void MinStackDestory(pMinStack mst);
void MinStackPush(pMinStack mst, DataType x);
void MinStackPop(pMinStack mst);
DataType MinStackTop(pMinStack mst);
int MinStackEmpty(pMinStack mst);
DataType MinStackMin(pMinStack mst);
Topic.c
#include "Topic.h"
void MinStackInit(pMinStack mst)//初始化
{
assert(mst);
StackInit(&(mst->st), 10);
StackInit(&(mst->minst), 10);
}
void MinStackPush(pMinStack mst, DataType x)//压栈
{
assert(mst);
StackPush(&(mst->st), x);
if (StackEmpty(&(mst->minst)) == 0 || StackTop(&(mst->minst)) >= x)
StackPush(&(mst->minst), x);
/*else
StackPush(&(mst->minst), StackTop(&(mst->minst)));*/
}
void MinStackPop(pMinStack mst)//出栈
{
assert(mst);
DataType x = StackTop(&(mst->st));
DataType min = StackTop(&(mst->minst));
StackPop(&(mst->st));
if (x == min)
StackPop(&(mst->minst));
}
DataType MinStackTop(pMinStack mst)//返回栈顶元素
{
assert(mst);
return StackTop(&(mst->st));
}
DataType MinStackMin(pMinStack mst)//返回最小值
{
assert(mst);
return StackTop(&(mst->minst));
}
int MinStackEmpty(pMinStack mst)//判断书否为空
{
assert(mst);
return StackEmpty(&(mst->st));
}
void MinStackDestory(pMinStack mst)//销毁
{
assert(mst);
StackDestory(&(mst->st));
StackDestory(&(mst->minst));
}

2) 使用两个栈实现一个队列 

#pragma once


#include "Stack.h"
#include <stdio.h>


typedef struct QueueBy2Stack {
Stack stack1;
Stack stack2;
} QueueBy2Stack;


void QueueBy2StackInit(QueueBy2Stack *pQ)
{
StackInit(&(pQ->stack1));
StackInit(&(pQ->stack2));
}
void QueueBy2StackDestroy(QueueBy2Stack *pQ)
{
StackDestroy(&(pQ->stack2));
StackDestroy(&(pQ->stack1));
}


void QueueBy2StackPush(QueueBy2Stack *pQ, int data)
{
StackPush(&(pQ->stack1), data);
}


static void __QueueBy2StackMove(QueueBy2Stack *pQ)
{
if (StackIsEmpty(&(pQ->stack2))) {
// 倒数据
while (!StackIsEmpty(&(pQ->stack1))) {
int data = StackTop(&(pQ->stack1));
StackPop(&(pQ->stack1));
StackPush(&(pQ->stack2), data);
}
}
}


void QueueBy2StackPop(QueueBy2Stack *pQ)
{
__QueueBy2StackMove(pQ);


assert(!StackIsEmpty(&(pQ->stack2)));
StackPop(&(pQ->stack2));
}


int QueueBy2StackFront(QueueBy2Stack *pQ)
{
__QueueBy2StackMove(pQ);


assert(!StackIsEmpty(&(pQ->stack2)));
return StackTop(&(pQ->stack2));
}




void TestQueueByTwoStack()
{
QueueBy2Stack queue;


QueueBy2StackInit(&queue);


QueueBy2StackPush(&queue, 1);
QueueBy2StackPush(&queue, 2);
QueueBy2StackPush(&queue, 3);
QueueBy2StackPush(&queue, 4);
QueueBy2StackPush(&queue, 5);


printf("%d\n", QueueBy2StackFront(&queue));
QueueBy2StackPop(&queue);


printf("%d\n", QueueBy2StackFront(&queue));
QueueBy2StackPop(&queue);


printf("%d\n", QueueBy2StackFront(&queue));
QueueBy2StackPop(&queue);


printf("%d\n", QueueBy2StackFront(&queue));
QueueBy2StackPop(&queue);


printf("%d\n", QueueBy2StackFront(&queue));
QueueBy2StackPop(&queue);


QueueBy2StackDestroy(&queue);
}

3) 使用两个队列实现一个栈 

#pragma once


#include "Queue.h"
#include <stdio.h>


typedef struct StackBy2Queue {
Queue queue1;
Queue queue2;
} StackBy2Queue;


void StackBy2QueueInit(StackBy2Queue *pS)
{
assert(pS);


QueueInit(&(pS->queue1));
QueueInit(&(pS->queue2));
}


void StackBy2QueueDestroy(StackBy2Queue *pS)
{
assert(pS);


QueueDestroy(&(pS->queue2));
QueueDestroy(&(pS->queue1));
}


void StackBy2QueuePush(StackBy2Queue *pS, int data)
{
Queue *pNotEmpty = &(pS->queue1);
Queue *pEmpty = &(pS->queue2);


if (!QueueIsEmpty(&(pS->queue2))) {
pNotEmpty = &(pS->queue2);
pEmpty = &(pS->queue1);
}


QueuePush(pNotEmpty, data);
}


void StackBy2QueuePop(StackBy2Queue *pS)
{
Queue *pNotEmpty = &(pS->queue1);
Queue *pEmpty = &(pS->queue2);
int data;


if (!QueueIsEmpty(&(pS->queue2))) {
pNotEmpty = &(pS->queue2);
pEmpty = &(pS->queue1);
}


while (QueueSize(pNotEmpty) > 1) {
data = QueueFront(pNotEmpty);
QueuePop(pNotEmpty);
QueuePush(pEmpty, data);
}


QueuePop(pNotEmpty);
}


int StackBy2QueueFront(StackBy2Queue *pS)
{
Queue *pNotEmpty = &(pS->queue1);
Queue *pEmpty = &(pS->queue2);
int data;


if (!QueueIsEmpty(&(pS->queue2))) {
pNotEmpty = &(pS->queue2);
pEmpty = &(pS->queue1);
}


while (QueueSize(pNotEmpty) > 1) {
data = QueueFront(pNotEmpty);
QueuePop(pNotEmpty);
QueuePush(pEmpty, data);
}


data = QueueFront(pNotEmpty);
QueuePop(pNotEmpty);
QueuePush(pEmpty, data);


return data;
}


void TestStackBy2Queue()
{
StackBy2Queue stack;


StackBy2QueueInit(&stack);


StackBy2QueuePush(&stack, 1);
StackBy2QueuePush(&stack, 2);
StackBy2QueuePush(&stack, 3);
StackBy2QueuePush(&stack, 4);


printf("%d\n", StackBy2QueueFront(&stack));
StackBy2QueuePop(&stack);


printf("%d\n", StackBy2QueueFront(&stack));
StackBy2QueuePop(&stack);


printf("%d\n", StackBy2QueueFront(&stack));
StackBy2QueuePop(&stack);


printf("%d\n", StackBy2QueueFront(&stack));
StackBy2QueuePop(&stack);


StackBy2QueueDestroy(&stack);
}

4) 元素出栈、入栈顺序的合法性。如入栈的序列(1,2,3,4,5),出栈序列为 (4,5,3,2,1) 

#pragma once


#include "Stack.h"
#include <stdio.h>
#include <string.h>


int IsOrderValid(char in[], int size_in, char out[], int size_out)
{
int i, j;
char outch, inch;
Stack stack;


if (size_in != size_out) {
return 0;
}


if (size_in == 0) {
return 1;
}


StackInit(&stack);


j = 0;
for (i = 0; i < size_out; i++) {
outch = out[i];


if (StackIsEmpty(&stack) || StackTop(&stack) != outch) {
for (; j < size_in; j++) {
inch = in[j];
StackPush(&stack, (int)inch);


if (out[i] == in[j]) {
j++;
break;
}
  }


#if 0
for (; out[i] != in[j] && j < size_in; j++) {
inch = in[j];
StackPush(&stack, (int)inch);
}


if (j != size_in) {
inch = in[j++];
StackPush(&stack, (int)inch);
}
#endif
}


if (j == size_in) {
if (outch != StackTop(&stack)) {
return 0;
}
}


StackPop(&stack);
}


return 1;
}


void TestIsOrderValid()
{
char *in = "abcdefg";
char *out = "decfbga";
printf("%s 是否合法: %s\n", out,
IsOrderValid(in, strlen(in), out, strlen(out)) ? "合法" : "不合法");
out = "fegdacb";
printf("%s 是否合法: %s\n", out,
IsOrderValid(in, strlen(in), out, strlen(out)) ? "合法" : "不合法");
out = "efdgbca";
printf("%s 是否合法: %s\n", out,
IsOrderValid(in, strlen(in), out, strlen(out)) ? "合法" : "不合法");
out = "cdbefag";
printf("%s 是否合法: %s\n", out,
IsOrderValid(in, strlen(in), out, strlen(out)) ? "合法" : "不合法");
}


5) 一个数组实现两个栈(共享栈)

#pragma once


#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>


#define CAPACITY (4)


typedef struct ShareStack {
int *array;
int capacity;
int top1;
int top2;
} ShareStack;


void Init(ShareStack *pStack)
{
pStack->array = (int *)malloc(sizeof(int)* CAPACITY);
pStack->capacity = CAPACITY;
pStack->top1 = 0;
pStack->top2 = 1;
}


void Destroy(ShareStack *pStack)
{
free(pStack->array);
pStack->array = NULL;
pStack->capacity = pStack->top1 = pStack->top2 = 0;
}


void ExpandIfRequired(ShareStack *pStack)
{
if ((pStack->top1 != pStack->capacity) && (pStack->top2 != pStack->capacity + 1)) {
return;
}


int oldCapacity = pStack->capacity;
pStack->capacity *= 2;


int *newArray = (int *)malloc(sizeof(int)* pStack->capacity);
assert(newArray != NULL);
memcpy(newArray, pStack->array, sizeof(int)* oldCapacity);


free(pStack->array);
pStack->array = newArray;
}


void Push(ShareStack *pStack, int which, int data)
{
ExpandIfRequired(pStack);


if (which == 1) {
pStack->array[pStack->top1] = data;
pStack->top1 += 2;
}
else {
pStack->array[pStack->top2] = data;
pStack->top2 += 2;
}
}




void Pop(ShareStack *pStack, int which)
{
assert(pStack != NULL);
assert(which == 1 || which == 2);
if (which == 1) {
assert(pStack->top1 > 0);
pStack->top1 -= 2;
}
else {
assert(pStack->top2 > 1);
pStack->top2 -= 2;
}
}


int Top(ShareStack *pStack, int which)
{
assert(pStack != NULL);
assert(which == 1 || which == 2);


if (which == 1) {
assert(pStack->top1 > 0);
return pStack->array[pStack->top1 - 2];
}
else {
assert(pStack->top2 > 1);
return pStack->array[pStack->top2 - 2];
}
}


void TestShareStack()
{
ShareStack stack;
int i;


Init(&stack);


Push(&stack, 1, 1);
Push(&stack, 1, 2);
Push(&stack, 1, 3);
Push(&stack, 1, 4);
Push(&stack, 1, 5);
Push(&stack, 2, 11);
Push(&stack, 2, 12);
Push(&stack, 2, 13);
Push(&stack, 2, 14);
Push(&stack, 2, 15);
Push(&stack, 2, 16);


for (i = 0; i < 5; i++) {
printf("%d\n", Top(&stack, 1));
Pop(&stack, 1);
}
for (i = 0; i < 6; i++) {
printf("%d\n", Top(&stack, 2));
Pop(&stack, 2);
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值