爱上数据结构:栈和队列的OJ及选择题


外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

🔥个人主页guoguoqiang. 🔥专栏数据结构

Alt

一、 栈和队列的OJ题

1.括号匹配问题

括号匹配问题
在这里插入图片描述

typedef char STDataType;
typedef struct Stack {
	STDataType* a;
	int top;
	int capacity;
}ST;
void STInit(ST* ps);
void STDestroy(ST* ps);
void STPush(ST* ps, STDataType x);
void STPop(ST* ps);
STDataType STTop(ST* ps);
int STSize(ST* ps);
bool STEmpty(ST* ps);
void STInit(ST* ps) {
	assert(ps);
	ps->a = NULL;
	ps->top = 0;
	ps->capacity = 0;
}
void STDestroy(ST* ps) {
	assert(ps);
	free(ps->a);
	ps->a = NULL;
	ps->top = ps->capacity = 0;
}
void STPush(ST* ps, STDataType x) {
	assert(ps);
	if (ps->top == ps->capacity) {
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		STDataType* tmp = (STDataType*)realloc(ps->a,sizeof(STDataType) * newcapacity);
		if (tmp == NULL) {
			perror("realloc fail");
			return;
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
	ps->a[ps->top] = x;
	ps->top++;
}
void STPop(ST* ps) {
	assert(ps);
	assert(!STEmpty(ps));
	ps->top--;
}
STDataType STTop(ST* ps) {
	assert(ps);
	assert(!STEmpty(ps));
	return ps->a[ps->top - 1];
}
int STSize(ST* ps) {
	assert(ps);
	return ps->top;
}
bool STEmpty(ST* ps) {
	assert(ps);
	return ps->top == 0;
}
bool isValid(char* s) {
    ST st;
    STInit(&st);
    while(*s){
        if(*s=='['||*s=='('||*s=='{'){
            STPush(&st,*s);
        }
        else{
            if(STEmpty(&st)){
                STDestroy(&st);
                return false;
            }
            char top =STTop(&st);
            STPop(&st);
            if((*s==']'&&top!='[')
            ||(*s=='}'&&top!='{')
            ||(*s==')'&&top!='('))
            {
                STDestroy(&st);
                return false;
            }
        }
        s++;
    }
    bool ret=STEmpty(&st);
    STDestroy(&st);
    return ret;
}

2.用队列实现栈

在这里插入图片描述
队列是先进先出,用两个队列实现栈,一个队列专门用来入数据,一个队列专门用来出数据,如果第二个队列为空之后再从第一个队列往第二个队列入数据。

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

typedef int QDataType;
typedef struct QueueNode
{
	int val;
	struct QueueNode* next;
}QNode;
typedef struct Queue
{
	QNode* phead;
	QNode* ptail;
	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);
bool QueueEmpty(Queue* pq);
int QueueSize(Queue* pq);

void QueueInit(Queue* pq)
{
	assert(pq);

	pq->phead = NULL;
	pq->ptail = NULL;
	pq->size = 0;
}

void QueueDestroy(Queue* pq)
{
	assert(pq);

	QNode* cur = pq->phead;
	while (cur)
	{
		QNode* next = cur->next;
		free(cur);

		cur = next;
	}

	pq->phead = pq->ptail = NULL;
	pq->size = 0;
}

// 入队列
void QueuePush(Queue* pq, QDataType x)
{
	assert(pq);
	QNode* newnode = (QNode*)malloc(sizeof(QNode));
	if (newnode == NULL)
	{
		perror("malloc fail");
		return;
	}

	newnode->val = x;
	newnode->next = NULL;

	if (pq->ptail)
	{
		pq->ptail->next = newnode;
		pq->ptail = newnode;
	}
	else
	{
		pq->phead = pq->ptail = newnode;
	}

	pq->size++;
}

// 出队列
void QueuePop(Queue* pq)
{
	assert(pq);

	// 0个节点
	// 温柔检查
	//if (pq->phead == NULL)
	//	return;

	// 暴力检查 
	assert(pq->phead != NULL);

	// 一个节点
	// 多个节点
	if (pq->phead->next == NULL)
	{
		free(pq->phead);
		pq->phead = pq->ptail = NULL;
	}
	else
	{
		QNode* next = pq->phead->next;
		free(pq->phead);
		pq->phead = next;
	}

	pq->size--;
}

QDataType QueueFront(Queue* pq)
{
	assert(pq);

	// 暴力检查 
	assert(pq->phead != NULL);

	return pq->phead->val;
}

QDataType QueueBack(Queue* pq)
{
	assert(pq);

	// 暴力检查 
	assert(pq->ptail != NULL);

	return pq->ptail->val;
}

bool QueueEmpty(Queue* pq)
{
	assert(pq);

	return pq->size == 0;
}

int QueueSize(Queue* pq)
{
	assert(pq);

	return pq->size;
}
typedef struct {
    Queue q1;
    Queue q2;
} MyStack;


MyStack* myStackCreate() {
    MyStack*pst=(MyStack*)malloc(sizeof(MyStack));
    QueueInit(&pst->q1);
    QueueInit(&pst->q2);
    return pst;
}

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

int myStackPop(MyStack* obj) {
    Queue*pEmptyQ=&obj->q1;
    Queue*pNonEmptyQ=&obj->q2;
    if(!QueueEmpty(&obj->q1)){
        pEmptyQ=&obj->q2;
        pNonEmptyQ=&obj->q1;
    }
    while(QueueSize(pNonEmptyQ)>1){
        int front =QueueFront(pNonEmptyQ);
        QueuePush(pEmptyQ,front);
        QueuePop(pNonEmptyQ);
    }
        int front =QueueFront(pNonEmptyQ);
        QueuePop(pNonEmptyQ);
        return front;
}

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.用栈实现队列

在这里插入图片描述

typedef int DataType;


typedef struct Stack {
	DataType* arr;
	int top;
	int capacity;
}Stack;


void StackInit(Stack* st) {//初始化
	assert(st);
	st->arr = NULL;
	st->capacity = 0;
	st->top = -1;
}

void CheckCapacity(Stack* st) {
	assert(st);
	if (st->top +1 == st->capacity) {
		//扩容
		int newcap = st->capacity == 0 ? 4 : 2 * st->capacity;
		DataType* tmp = (DataType*)realloc(st->arr, newcap * sizeof(DataType));  //注意点。开辟的空间大小为字节数
		if (NULL == tmp) {
			perror("realloc fail\n");
			exit(-1);
		}
		st->arr = tmp;
		st->capacity = newcap;
	}
}

bool Empty(Stack* st) { //栈是否为空
	assert(st);
	return st->top == -1;
}

void StackPush(Stack* st, DataType x) {//入栈
	assert(st);
	CheckCapacity(st);
	st->arr[++st->top] = x;
}

void StackPop(Stack* st) { //出栈
	assert(st);
	if (Empty(st)) {
		return;
	}
	st->top--;
}

DataType StackTop(Stack* st) { //获取栈顶元素
	assert(st);
	if (Empty(st)) {
		return -1; //栈为空理应报错
	}
	return st->arr[st->top];
}

void StackDestory(Stack* st) {
	assert(st);
	if (st->arr) {
		free(st->arr);
	}
	st->capacity = 0;
	st->top = -1;
}

void StackPrint(Stack* st) {
	assert(st);
	if (Empty(st)) {
		printf("STACK IS EMPTY\n");
		return;
	}

	for (int i = 0;i <= st->top;++i) {
		printf("%d ", st->arr[i]);
	}
	printf("\n");
}


void StackInit(Stack* st);//初始化

void CheckCapacity(Stack* st); //检测是否需要扩容

void StackPush(Stack* st, DataType x); //入栈

void StackPop(Stack* st); //出栈

DataType StackTop(Stack* st); //获取栈顶元素

void StackDestory(Stack* st); //销毁栈

bool Empty(Stack* st); //栈是否为空

void StackPrint(Stack* st); //打印栈内数据




typedef struct {
    Stack _inqueue;
    Stack _outqueue;
} MyQueue;


MyQueue* myQueueCreate() {
    MyQueue* mq = (MyQueue*)malloc(sizeof(MyQueue));
    StackInit(&mq->_inqueue);
    StackInit(&mq->_outqueue);
    return mq;
}

void myQueuePush(MyQueue* obj, int x) {
    StackPush(&obj->_inqueue,x);
}

int myQueuePop(MyQueue* obj) {
    if(Empty(&obj->_outqueue)){
        while(!Empty(&obj->_inqueue)){
        DataType x = StackTop(&obj->_inqueue);
        StackPop(&obj->_inqueue);
        StackPush(&obj->_outqueue,x);
        }
    }
    DataType out = StackTop(&obj->_outqueue);
    StackPop(&obj->_outqueue);
    return out;
}

int myQueuePeek(MyQueue* obj) {
        if(Empty(&obj->_outqueue)){
        while(!Empty(&obj->_inqueue)){
        DataType x = StackTop(&obj->_inqueue);
        StackPop(&obj->_inqueue);
        StackPush(&obj->_outqueue,x);
        }
    }
    DataType out = StackTop(&obj->_outqueue);
    return out;
}

bool myQueueEmpty(MyQueue* obj) {
    return Empty(&obj->_inqueue) && Empty(&obj->_outqueue);
}

void myQueueFree(MyQueue* obj) {
    StackDestory(&obj->_inqueue);
    StackDestory(&obj->_outqueue);
}

二、选择题

1.一个栈的初始状态为空。现将元素1、2、3、4、5、A、B、C、D、E依次入栈,然后再依次出栈,则元素出
栈的顺序是( )。
A 12345ABCDE
B EDCBA54321
C ABCDE12345
D 54321EDCBA

栈是后进先出所以选B

2.若进栈序列为 1,2,3,4 ,进栈过程中可以出栈,则下列不可能的一个出栈序列是()
A 1,4,3,2
B 2,3,4,1
C 3,1,4,2
D 3,4,2,1

栈可以入一个出一个,但是不能切换顺序 C

3.循环队列的存储空间为 Q(1:100) ,初始状态为 front=rear=100 。经过一系列正常的入队与退队操作
后, front=rear=99 ,则循环队列中的元素个数为( )
A 1
B 2
C 99
D 0或者100

D

4.以下( )不是队列的基本运算?
A 从队尾插入一个新元素
B 从队列中删除第i个元素
C 判断一个队列是否为空
D 读取队头元素的值

B

5.现有一循环队列,其队头指针为front,队尾指针为rear;循环队列长度为N。其队内有效长度为?(假设队头不存放数据)
A (rear - front + N) % N + 1
B (rear - front + N) % N
C (rear - front) % (N + 1)
D (rear - front + N) % (N - 1)

在正常不考虑超出的情况下为满是rear-front,但是要考虑是否rear在前,而front在后,所以最后的答案为(rear-front+N)%N,%N就可以防止超出范围。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值