2024年C C++最新史上最强数据结构----栈和队列相关笔试面试题_关于栈的笔试考题,2024年最新金三银四我带你去BAT面试现场

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

首先将所给的字符串进行遍历,如果是左括号就将它压入栈中,根据栈后进先出的特性,然后逐个取出栈中的左括号与后面剩下的右括号进行逐对进行匹配,如果不匹配就返回false,如果都匹配了就返回true。

例如:

代码:

typedef char STDataType;
typedef struct Stack
{
	STDataType* a;
	int top;//栈顶的位置
	int capacity;//容量
}ST;
void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}
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->top == ps->capacity)//满了进行扩容
	{
		int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		ps->a = (STDataType*)realloc(ps->a,sizeof(STDataType)*newCapacity);
		if (ps->a == NULL)
		{
			printf("fail malloc\n");
			exit(-1);
		}
		ps->capacity = newCapacity;
	}
	ps->a[ps->top++] = x;
}
void StackPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	--ps->top;
}
bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}
STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);

	return ps->a[ps->top - 1];
}
int SizeStack(ST* ps)
{
	assert(ps);
	return ps->top;
}
//前面的所有代码就是定义一个栈以及栈的相关函数
bool isValid(char * s){
    ST st;
    StackInit(&st);
    while(*s)
    {
        if(*s=='['||*s=='('||*s=='{')
        {
            StackPush(&st,*s);
            ++s;
        }
        else
        {
            if(StackEmpty(&st))//当所给的字符串中只有右括号时直接返回false
            {
                StackDestory(&st);
                return false;
            }
            char top = StackTop(&st);//从栈中取一个左括号
            StackPop(&st);//进行出栈操作,让刚才取的字符出栈
            if((*s==']'&&top!='[')
            ||(*s=='}'&&top!='{')
            ||(*s==')'&&top!='('))//两个字符不相匹配的情况下直接返回false
            {
                StackDestory(&st);
                return false;
            }
            else
            {
                ++s;
            }
        }
    }
    //栈为空,说明所有左括号都匹配了
    bool ret =  StackEmpty(&st);//判断是否只有左括号,如果只有左括号此时ret就为false,如果前面都已经匹配完了ret就等于true
    StackDestory(&st);
    return ret;
}

1.2 用队列实现栈

image-20220327105221958

解析上面的实例:

输入的第一行是执行的操作。第二行是执行操作的数据。

输出是对应的返回值。

思路:用两个队列实现栈。

栈的基本结构:

image-20220327204730285

1、入栈,push数据到不为空的队列。

2、出栈,把不为空的队列的数据前N-1导入到另一个空队列,最后剩下的一个删掉。

image-20220327205910564

代码:

typedef int QDataType;
typedef struct QueueNode
{
	QDataType data;
	struct QueueNode* next;
}QNode;
typedef struct Queue
{
	QNode* head;
	QNode* tail;
}Queue;
void QueueInit(Queue* pq);
void QueueDestory(Queue* pq);
void QueuePush(Queue*pq,QDataType x);
void QueuePop(Queue*pq);
size_t QueueSize(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
bool QueueEmpty(Queue* pq);
void QueueInit(Queue* pq)
{
	assert(pq);
	pq->head =pq->tail = NULL;
}
QNode* BuyQNode(QDataType x)
{
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		printf("fail malloc\n");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = BuyQNode(x);
	if (pq->tail == NULL)
	{
		assert(pq->head == NULL);
		pq->head= pq->tail = newnode;
	}
	else
	{
		pq->tail->next = newnode;
		pq->tail = newnode;
	}
	
}
void QueuePop(Queue* pq)
{
	assert(pq);
	assert(pq->tail&&pq->head);
	if (pq->head->next==NULL)//处理只有一个节点的时候
	{
		free(pq->tail);
		pq->tail = pq->head = NULL;
	}
	else//有多个节点
	{
		QNode* next = pq->head->next;
		free(pq->head);
		pq->head = next;
	}
}
size_t QueueSize(Queue* pq)
{
	assert(pq);
	size_t size = 0;
	QNode* cur = pq->head;
	while (cur!= pq->tail->next)
	{
		size++;
		cur = cur->next;
	}
	return size;
}
QDataType QueueFront(Queue* pq)
{
	assert(pq);
	assert(pq->head);
	return pq->head->data;
}
QDataType QueueBack(Queue* pq)
{
	assert(pq);
	assert(pq->tail);
	return pq->tail->data;
}
void QueueDestory(Queue* pq)
{
	assert(pq);
	QNode* cur = pq->head;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);
		cur = next;
	}
	pq->head = pq->tail = NULL;
}
bool QueueEmpty(Queue* pq)
{
	assert(pq);
	return pq->head==NULL&&pq->tail==NULL;
}
typedef struct {
    Queue q1;
    Queue q2;
} MyStack;


MyStack* myStackCreate() {
    MyStack* pst = (MyStack*)malloc(sizeof(MyStack));
    assert(pst);
    QueueInit(&pst->q1);//这一行代码和后面这一行代码等价:QueueInit(&(pst->q1));
    QueueInit(&pst->q2);//这一行代码和后面这一行代码等价:QueueInit(&(pst->q2));
    return pst;
}

void myStackPush(MyStack* obj, int x) {
    assert(obj);
    if(!QueueEmpty(&obj->q1))
    {
        QueuePush(&obj->q1,x);
    }
    else
    {
        QueuePush(&obj->q2,x);
    }
}

int myStackPop(MyStack* obj) {
    assert(obj);
    Queue *emptyQ = &obj->q1;
    Queue*nonEmptyQ = &obj->q2;
    if(!QueueEmpty(&obj->q1))
    {
        emptyQ = &obj->q2;
        nonEmptyQ = &obj->q1;
    }
    //把非空队列的前N个数据,导入空队列,剩下一个删掉
    //就实现了后进先出
    while(QueueSize(nonEmptyQ)>1)
    {
        QueuePush(emptyQ,QueueFront(nonEmptyQ));//将非空队列的队头数据push到非空队列中
        QueuePop(nonEmptyQ);//将非空队列的队头数据出队
    }
    QDataType top = QueueFront(nonEmptyQ);
    QueuePop(nonEmptyQ);
    return top;
}

int myStackTop(MyStack* obj) {
    assert(obj);
    
    if(!QueueEmpty(&obj->q1))
    {
        return QueueBack(&obj->q1);
    }
    else
    {
        return QueueBack(&obj->q2);
    }
   
}
bool myStackEmpty(MyStack* obj) {
    assert(obj);
    return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}

void myStackFree(MyStack* obj) {
    assert(obj);
    QueueDestory(&obj->q1);
    QueueDestory(&obj->q2);
    free(obj);
}

1.3 用栈实现队列

image-20220330222159195

思路:

image-20220330221422700

注意:在上面的代码中,在进行出队操作时,只要popST这个栈中有数据,那么我们就不进行倒数据的操作(即将push中的数据倒到popST这个栈中),只有当pop中的数据为空且我们要进行出队时才进行倒数据。

队列结构:

image-20220330225340619

代码:

typedef int STDataType;
//数组栈的实现
typedef struct Stack
{
	STDataType* a;
	int top;//栈顶的位置
	int capacity;//容量
}ST;
void StackInit(ST* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->capacity = 0;
	ps->top = 0;
}
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->top == ps->capacity)//满了进行扩容
	{
		int newCapacity = ps->capacity == 0 ? 2 : 2 * ps->capacity;
		STDataType*new = (STDataType*)realloc(ps->a,sizeof(STDataType)*newCapacity);
		if (new == NULL)
		{
			printf("fail malloc\n");
			exit(-1);
		}
		ps->a = new;
		ps->capacity = newCapacity;
	}
	ps->a[ps->top++] = x;
}
void StackPop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);
	--ps->top;
}
bool StackEmpty(ST* ps)
{
	assert(ps);
	return ps->top == 0;
}
STDataType StackTop(ST* ps)
{
	assert(ps);
	assert(ps->top > 0);

	return ps->a[ps->top - 1];
}
int SizeStack(ST* ps)
{
	assert(ps);
	return ps->top;
}
void StackInit(ST*ps);
void StackDestory(ST* ps);
void StackPush(ST* ps,STDataType x);
void StackPop(ST* ps);
bool StackEmpty(ST* ps);
int SizeStack(ST* ps);
STDataType StackTop(ST* ps);
typedef struct {
    ST pushST;
    ST popST;
} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue * myQueue = (MyQueue*)malloc(sizeof(MyQueue));
    assert(myQueue);
    StackInit(&myQueue->pushST);
    StackInit(&myQueue->popST);
    return myQueue;
}

void myQueuePush(MyQueue* obj, int x) {
    assert(obj);
    StackPush(&obj->pushST,x);//入队直接向pushST插入即可
}

int myQueuePop(MyQueue* obj){
    assert(obj);
    if(StackEmpty(&obj->popST))//push为空,就进行倒数据,就符合先进先出的顺序了
    {
        while(!StackEmpty(&obj->pushST))
        {
            StackPush(&obj->popST,StackTop(&obj->pushST));
            StackPop(&obj->pushST);
        }
    }
    STDataType ret = StackTop(&obj->popST);//临时保存返回的数据
    StackPop(&obj->popST);
    return ret;
}

int myQueuePeek(MyQueue* obj) {
    assert(obj);
    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) {


![img](https://img-blog.csdnimg.cn/img_convert/820139a4bdc2d1add97381407ae672e4.png)
![img](https://img-blog.csdnimg.cn/img_convert/9c35e064bdc38b56fdc65b3c38b012c5.png)

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

&obj->popST);
}

bool myQueueEmpty(MyQueue* obj) {
    assert(obj);
    return StackEmpty(&obj->pushST)&&StackEmpty(&obj->popST);
}

void myQueueFree(MyQueue* obj) {


[外链图片转存中...(img-1Pvp7XD3-1715561667156)]
[外链图片转存中...(img-B5hGIZem-1715561667156)]

**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**


**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值