目录
一、选择题
二、栈和队列的面试题
1、括号匹配问题
1.1 题目说明
1.2 题目解析
2、用队列实现栈
2.1 题目说明
2.2 题目解析
3、用栈实现队列
3.1 题目说明
3.2 题目解析
一、选择题
1、若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是( C )
A: 1,4,3,2 B: 2,3,4,1 C: 3,1,4,2 D: 3,4,2,1
解析:A:先进1,然后出1,连续进2,3,4,然后出栈就是4,3,2.
B:先进1,2,然后出2,再进3,然后出3,再进4,然后出4,最后再出1.
C:先进1,2,3,然后出3,下一个出栈的要么是2,要么是4先进栈,然后4再出栈。
D:先进1,2,3,然后出3,再进4,然后出4,接着再出2,再出1。
2、一个栈的初始状态为空。现将元素1、2、3、4、5、A、B、C、D、E依次入栈,然后再依次出栈,则元素出 栈的顺序是( B )
A: 12345ABCDE B: EDCBA54321 C: ABCDE12345 D: 54321EDCBA
3、现有一循环队列,其队头指针为front,队尾指针为rear;循环队列长度为N。其队内有效长度为?(假设 队头不存放数据) ( B )
A:(rear - front + N) % N + 1 B:(rear - front + N) % N
C:(rear - front) % (N + 1) D:(rear - front + N) % (N - 1)
二、栈和队列的面试题
1、括号匹配问题
1.1 题目说明
题目链接:括号匹配问题
给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
1、左括号必须用相同类型的右括号闭合。
2、左括号必须以正确的顺序闭合。
3、每个右括号都有一个对应的相同类型的左括号。
1.2 题目解析
思路:先让左括号入栈,当取到右括号时,就用这个右括号和进栈的左括号进行匹配,若能够成功匹配就接着往下,否则就返回false,当全部取完的时候都没有返回false时就返回true. 最后还要考虑栈不为空的情况:(1)如果都是左括号,形如“(( ”,根本不出栈 ;(2)假如直接是空的字符串或者只有右括号。
typedef char STDataType;
typedef struct Stack
{
STDataType* a;//数组
int capacity;
int top; //初始为0,表示栈顶位置下一个位置的下标
}ST;
// 初始化栈
void StackInit(ST* ps);
//销毁
void StackDestory(ST* ps);
//入栈
void StackPush(ST* ps, STDataType x);
//出栈
void StackPop(ST* ps);
//获取栈顶元素
STDataType StackTop(ST* ps);
//获取栈中有效元素个数
int StackSize(ST* ps);
bool StackEmpty(ST* ps);
// 初始化栈
void StackInit(ST* ps)
{
assert(ps);
//ps->a = NULL;
//ps->top = 0;
//ps->capacity = 0;
ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
if (ps->a == NULL)
{
perror("malloc fail");
exit(-1);
}
ps->top = 0;
ps->capacity = 4;
}
//销毁
void StackDestory(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = ps->top = 0;
}
//入栈
void StackPush(ST* ps, STDataType x)
{
assert(ps);
//扩容
if (ps->capacity == ps->top)
{
STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
ps->a = tmp;
ps->capacity *= 2;
}
ps->a[ps->top] = x;
ps->top++;
}
//出栈
void StackPop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
ps->top--;
}
//获取栈顶元素
STDataType StackTop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top - 1];
}
//获取栈中有效元素个数
int StackSize(ST* ps)
{
assert(ps);
return ps->top;
}
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
bool isValid(char * s){
ST st;
StackInit(&st);
while(*s)
{
if(*s == '[' || *s == '{' || *s == '(')
{
StackPush(&st,*s);
s++;
}
else
{
if(StackEmpty(&st))
{
StackDestory(&st);
return false;
}
char top = StackTop(&st);
StackPop(&st);
//不匹配
if((*s == ']' && top != '[')
|| (*s == '}' && top != '{')
|| (*s == ')' && top != '('))
{
StackDestory(&st);
return false;
}
else//继续
{
s++;
}
}
}
bool ret = StackEmpty(&st);//栈为空,为真(true)
StackDestory(&st);
return ret;
}
2、用队列实现栈
2.1 题目说明
题目链接:用队列实现栈
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push
、top
、pop
和 empty
)。
实现MyStack类:
- void push(int x) 将元素 x 压入栈顶。
- int pop() 移除并返回栈顶元素。
- int top() 返回栈顶元素。
- boolean empty() 如果栈是空的,返回
true
;否则,返回false
。
2.2 题目解析
用队列实现栈,队列的功能是先进先出,而栈功能是先进后出。
思路:所以就要创建两个队列,让其中一个队列为空队列,然后另一个队列插入数据。删除数据时,有数据的队列开始出队列,直接进入另一个空队列中,直到先前有数据的队列出到size=1时,然后再删除数据。如果还要再入数据,就入到有数据的队列,保证另一个队列为空。
因此,我们需要自己先创建一个队列,然后再用队列实现栈。
typedef int QDataType;
// 链式结构:表示队列
typedef struct QueueNode
{
QDataType data;
struct QueueNode* next;
}QNode;
// 队列的结构
typedef struct Queue
{
QNode* head;
QNode* tail;
int size;
}Queue;
// 初始化队列
void QueueInit(Queue* pq);
// 销毁队列
void QueueDestroy(Queue* pq);
// 队尾入队列
void QueuePush(Queue* pq, QDataType x);
// 队头出队列
void QueuePop(Queue* pq);
// 获取队列头部元素
QDataType QueueFront(Queue* pq);
// 获取队列队尾元素
QDataType QueueBack(Queue* pq);
// 获取队列中有效元素个数
int QueueSize(Queue* pq);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Queue* pq);
// 初始化队列
void QueueInit(Queue* pq)
{
assert(pq);
pq->head = pq->tail = NULL;
pq->size = 0;
}
// 销毁队列
void QueueDestroy(Queue* pq)
{
assert(pq);
QNode* cur = pq->head;
while (cur)
{
QNode* del = cur;
cur = cur->next;
free(del);
//del = NULL;
}
pq->head = pq->tail = NULL;
pq->size = 0;
}
// 队尾入队列
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
perror("malloc fail");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
if (pq->tail == NULL)
{
pq->head = pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
pq->size++;
}
// 队头出队列
void QueuePop(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
if (pq->head->next == NULL)//只有一个结点
{
free(pq->head);
pq->head = pq->tail = NULL;
}
else
{
QNode* del = pq->head;
pq->head = pq->head->next;
free(del);
}
pq->size--;
}
// 获取队列头部元素
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->head->data;
}
// 获取队列队尾元素
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(!QueueEmpty(pq));
return pq->tail->data;
}
// 获取队列中有效元素个数
int QueueSize(Queue* pq)
{
int size = 0;
return pq->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head == NULL && pq->tail == NULL;
}
typedef struct {
Queue q1;
Queue q2;
} MyStack;
//需要自己创建结构体,并进行初始化
MyStack* myStackCreate() {
MyStack*obj = (MyStack*)malloc(sizeof(MyStack));
QueueInit(&obj->q1);
QueueInit(&obj->q2);
return obj;
}
void myStackPush(MyStack* obj, int x) {
if(!QueueEmpty(&obj->q1))
{
QueuePush(&obj->q1,x);
}
else
{
QueuePush(&obj->q2,x);
}
}
int myStackPop(MyStack* obj) {
Queue* emptyQ = &obj->q1;
Queue* nonemptyQ = &obj->q2;
if(!QueueEmpty(&obj->q1))
{
emptyQ = &obj->q2;
nonemptyQ = &obj->q1;
}
//非空队列的前n-1个数据倒入空队列
while(QueueSize(nonemptyQ) > 1)
{
QueuePush(emptyQ,QueueFront(nonemptyQ));
QueuePop(nonemptyQ);
}
int top = QueueFront(nonemptyQ);
QueuePop(nonemptyQ);
return top;
}
int myStackTop(MyStack* obj) {
if(!QueueEmpty(&obj->q1))
{
return QueueBack(&obj->q1);
}
else
{
return QueueBack(&obj->q2);
}
}
bool myStackEmpty(MyStack* obj) {
return QueueEmpty(&obj->q1) && QueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj) {
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
free(obj);
}
3、用栈实现队列
3.1 题目说明
题目链接:用栈实现队列
请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push
、top
、pop
和 empty
)。
实现MyStack类:
- void push(int x) 将元素 x 压入栈顶。
- int pop() 移除并返回栈顶元素。
- int top() 返回栈顶元素。
- boolean empty() 如果栈是空的,返回
true
;否则,返回false
。
3.2 题目解析
思路:用两个栈实现队列,一个pushst栈,一个popst栈。只要插入数据,我们就将数据放到pushst栈中,想要删除数据,就可以直接删除popst栈中的数据,如果popst栈为空,就将pushst栈的全部数据放到popst栈中,直到popst栈为空时,再将pushst栈中的数据倒入到popst栈中。
typedef int STDataType;
typedef struct Stack
{
STDataType* a;//数组
int capacity;
int top; //初始为0,表示栈顶位置下一个位置的下标
}ST;
// 初始化栈
void StackInit(ST* ps);
//销毁
void StackDestory(ST* ps);
//入栈
void StackPush(ST* ps, STDataType x);
//出栈
void StackPop(ST* ps);
//获取栈顶元素
STDataType StackTop(ST* ps);
//获取栈中有效元素个数
int StackSize(ST* ps);
bool StackEmpty(ST* ps);
// 初始化栈
void StackInit(ST* ps)
{
assert(ps);
//ps->a = NULL;
//ps->top = 0;
//ps->capacity = 0;
ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
if (ps->a == NULL)
{
perror("malloc fail");
exit(-1);
}
ps->top = 0;
ps->capacity = 4;
}
//销毁
void StackDestory(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity = ps->top = 0;
}
//入栈
void StackPush(ST* ps, STDataType x)
{
assert(ps);
//扩容
if (ps->capacity == ps->top)
{
STDataType* tmp = (STDataType*)realloc(ps->a, ps->capacity * 2 * sizeof(STDataType));
if (tmp == NULL)
{
perror("realloc fail");
exit(-1);
}
ps->a = tmp;
ps->capacity *= 2;
}
ps->a[ps->top] = x;
ps->top++;
}
//出栈
void StackPop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
ps->top--;
}
//获取栈顶元素
STDataType StackTop(ST* ps)
{
assert(ps);
assert(!StackEmpty(ps));
return ps->a[ps->top - 1];
}
//获取栈中有效元素个数
int StackSize(ST* ps)
{
assert(ps);
return ps->top;
}
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
typedef struct {
ST pushst;
ST popst;
} MyQueue;
bool myQueueEmpty(MyQueue* obj);
int myQueuePeek(MyQueue* obj);
//需要自己创建结构体,并进行初始化
MyQueue* myQueueCreate() {
MyQueue* pq = (MyQueue*)malloc(sizeof(MyQueue));
StackInit(&pq->pushst);
StackInit(&pq->popst);
return pq;
}
void myQueuePush(MyQueue* obj, int x) {
assert(obj);
StackPush(&obj->pushst,x);
}
int myQueuePop(MyQueue* obj) {
assert(obj);
assert(!myQueueEmpty(obj));
int peek = myQueuePeek(obj);
StackPop(&obj->popst);
return peek;
}
//对头
int myQueuePeek(MyQueue* obj) {
assert(obj);
assert(!myQueueEmpty(obj));
//pushst中的数据倒入popst中
if(StackEmpty(&obj->popst))
{
while(!StackEmpty(&obj->pushst))
{
StackPush(&obj->popst,StackTop(&obj->pushst));
StackPop(&obj->pushst);
}
}
return StackTop(&obj->popst);
}
bool myQueueEmpty(MyQueue* obj) {
assert(obj);
return StackEmpty(&obj->pushst) && StackEmpty(&obj->popst);
}
void myQueueFree(MyQueue* obj) {
assert(obj);
StackDestory(&obj->pushst);
StackDestory(&obj->popst);
free(obj);
}
本文要是有不足的地方,欢迎大家在下面评论,我会在第一时间更正。
老铁们,记着点赞加关注!!!