[Data structure] Stack and queue multiple choice questions and interview programming questions

Table of contents

1. Multiple choice questions

2. Interview questions about stacks and queues

  1. Bracket matching problem

     1.1 Description of the topic

     1.2 Topic analysis

  2. Implementing a stack with a queue

     2.1 Description of the topic

     2.2 Topic analysis

  3. Implement queue with stack

     3.1 Description of the topic

     3.2 Topic analysis


1. Multiple choice questions

1. If the push sequence is 1, 2, 3, 4, and the stack can be popped during the push process, then the following impossible pop sequence is ( C )

A: 1,4,3,2     B: 2,3,4,1      C: 3,1,4,2     D: 3,4,2,1

Analysis: A: Advance 1, then output 1, continuously enter 2, 3, 4, and then pop out 4, 3, 2.

           B: Advance 1, 2, then 2, then 3, then 3, then 4, then 4, and finally 1.

           C: Advance 1, 2, 3, then pop 3, and the next one to pop is either 2 or 4, and then 4 pops out.

           D: Advance 1, 2, 3, then out 3, then in 4, then out 4, then out 2, then out 1.

2. The initial state of a stack is empty. Now put the elements 1, 2, 3, 4, 5, A, B, C, D, E into the stack in sequence, and then pop them out in sequence, the order of the elements popping out is ( B )

A: 12345ABCDE      B: EDCBA54321       C: ABCDE12345       D: 54321EDCBA

3. There is a circular queue, the queue head pointer is front, and the tail pointer is rear; the length of the circular queue is N. What is the effective length in the team? (assuming no data is stored at the head of the queue) ( ​​B )

A:(rear - front + N) % N + 1           B:(rear - front + N) % N

C:(rear - front) % (N + 1)               D:(rear - front + N) % (N - 1)

2. Interview questions about stacks and queues

  1. Bracket matching problem

     1.1 Description of the topic

      Topic link: Bracket matching problem

      Given a string s consisting only of '(', ')', '{', '}', '[', ']', determine whether the string is valid.

      A valid string must satisfy:

1. A left parenthesis must be closed with a right parenthesis of the same type.
2. The opening brackets must be closed in the correct order.
3. Each closing bracket has a corresponding opening bracket of the same type.

 

     1.2 Topic analysis

   Idea: Let the left parenthesis be pushed onto the stack first. When the right parenthesis is fetched, use the right parenthesis to match the stacked left parenthesis. If the match can be successful, then go down. Otherwise, return false. When all are fetched Return true when neither returns false. Finally, consider the case that the stack is not empty: (1) If they are all left brackets, such as "(( ", they will not leave the stack at all; (2) If they are directly empty characters string or just the closing parenthesis.

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. Implementing a stack with a queue

     2.1 Description of the topic

      Topic link: Implementing a stack with a queue

      Please use only two queues to implement a last-in-first-out (LIFO) stack, and support all four operations ( push, top, pop and  empty) of a normal stack.

      Implement the MyStack class:

  • void push(int x) pushes the element x onto the top of the stack.
  • int pop() removes and returns the top element of the stack.
  • int top() Returns the top element of the stack.
  • boolean empty() Returns if the stack is empty  true ; otherwise, returns  false .

     2.2 Topic analysis

A queue is used to implement a stack. The function of the queue is first in first out, while the function of the stack is first in last out. 

Idea: So we need to create two queues, let one queue be an empty queue, and then insert data into the other queue. When deleting data, the queue with data starts to leave the queue, and directly enters another empty queue until the queue with data before goes out to size=1, and then deletes the data. If you want to re-enter data, enter the queue with data to ensure that the other queue is empty.

Therefore, we need to create a queue ourselves, and then use the queue to implement the stack. 

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. Implement queue with stack

     3.1 Description of the topic

      Topic Link: Implementing a Queue with a Stack

      Please use only two queues to implement a last-in-first-out (LIFO) stack, and support all four operations ( push, top, pop and  empty) of a normal stack.

      Implement the MyStack class:

  • void push(int x) pushes the element x onto the top of the stack.
  • int pop() removes and returns the top element of the stack.
  • int top() Returns the top element of the stack.
  • boolean empty() Returns if the stack is empty  true ; otherwise, returns  false .

     3.2 Topic analysis

Idea: Use two stacks to implement the queue, one pushst stack and one popst stack. As long as the data is inserted, we put the data in the pushst stack. If you want to delete the data, you can directly delete the data in the popst stack. If the popst stack is empty, put all the data in the pushst stack into the popst stack until the popst When the stack is empty, pour the data in the pushst stack into the popst stack.

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);
}


If there are deficiencies in this article, you are welcome to comment below, and I will correct it as soon as possible.

Old irons, remember to like and pay attention!!! 

 

Guess you like

Origin blog.csdn.net/m0_63198468/article/details/131002509