🔥个人主页:guoguoqiang. 🔥专栏:数据结构
一、 栈和队列的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就可以防止超出范围。