栈和队列的相关题目
- 循环队列
- 用队列实现栈
- 用栈实现队列
- 括号匹配
20. 有效的括号
输入:s = “()” 输入:s = “()[]{}”
输出:true 输出:true
// 将 左括号 ([{ 入栈,遇到右括号 )]} 时 看与栈顶的括号是否配对。
// 配对即将栈顶的括号出栈,不配对即返回false;
char pairs(char ch){ // 如果是右括号 即返回配对的左括号,否则返回自身
if(ch==']') return '[';
if(ch=='}') return '{';
if(ch==')') return '(';
return ch;
}
bool isValid(char * s){
int len=strlen(s);
if(len%2==1) // 单数不可能配对
return false;
int *arr=(int*)malloc(sizeof(int)*len);
int top=0; // 栈顶
char* str = s;
while (*str!='\0') {
if(*str!=pairs(*str)){ // 如果是右括号...
if(top==0)
return false;
if(arr[top-1]==pairs(*str)) // 配对了就出栈
top--;
else
return false;
}
else // 左括号
arr[top++]=*str; // 入栈
str++;
}
return top==0; // 如果top=0即全部完成配对,返回1;如果top不等于0,不能全部配对,返回0;
}
225. 用队列实现栈
// 定义两个队列,push存放入栈数据,pop存放出栈数据
// 每次出栈,将push队列的数据 倒置存入 pop队列,pop进行头删就相当于出栈
//*************************************************************队列的实现
// 链式结构:表示队列
typedef int QDataType;
typedef struct QListNode {
struct QListNode* next;
QDataType data;
}QNode;
// 队列的结构
typedef struct Queue {
QNode* head;
QNode* tail;
size_t size;
}Queue;
// 初始化队列
void QueueInit(Queue* q);
// 销毁队列
void QueueDestory(Queue* q);
// 队尾入队列
void QueuePush(Queue* q, QDataType data);
// 队头出队列
void QueuePop(Queue* q);
// 获取队列头部元素
QDataType QueueFront(Queue* q);
// 获取队列队尾元素
QDataType QueueBack(Queue* q);
// 获取队列中有效元素个数
int QueueSize(Queue* q);
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q);
// 初始化队列
void QueueInit(Queue* q) {
assert(q);
q->head = q->tail = NULL;
q->size = 0;
}
// 销毁队列
void QueueDestory(Queue* q) {
assert(q);
QNode* cur = q->head;
while (cur) {
QNode* del = cur;
cur = cur->next;
free(del);
}
q->head = q->tail = NULL;
}
// 队尾入队列
void QueuePush(Queue* q, QDataType data) {
assert(q);
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL) {
perror("malloc fail");
exit(-1);
}
else {
newnode->data = data;
newnode->next = NULL;
}
if (q->tail == NULL) {
q->head = q->tail = newnode;
}
else {
q->tail->next = newnode;
q->tail = newnode;
}
q->size++;
}
// 队头出队列
void QueuePop(Queue* q) {
assert(q);
assert(!QueueEmpty(q));
if (q->head->next == NULL) {
free(q->head);
q->head = q->tail = NULL;
}
else {
QNode* first = q->head;
q->head = first->next;
free(first);
first = NULL;
}
q->size--;
}
// 获取队列头部元素
QDataType QueueFront(Queue* q) {
assert(q);
assert(!QueueEmpty(q));
return q->head->data;
}
// 获取队列队尾元素
QDataType QueueBack(Queue* q) {
assert(q);
assert(!QueueEmpty(q));
return q->tail->data;
}
// 获取队列中有效元素个数
int QueueSize(Queue* q) {
assert(q);
return q->size;
}
// 检测队列是否为空,如果为空返回非零结果,如果非空返回0
int QueueEmpty(Queue* q) {
assert(q);
return (q->head == NULL && q->tail == NULL);
}
//*************************************************************队列的实现
typedef struct {
Queue push; // 存放入栈数据
Queue pop; // 存放出栈数据
} MyStack;
MyStack* myStackCreate() { // 初始化
MyStack* obj = (MyStack*)malloc(sizeof(MyStack));
QueueInit(&obj->push);
QueueInit(&obj->pop);
return obj;
}
bool myStackEmpty(MyStack* obj) { // 判空
return (QueueEmpty(&obj->pop) && QueueEmpty(&obj->push));
}
void PushToPop(MyStack* obj) {
if (QueueEmpty(&obj->pop) ){
int size = obj->push.size;
int* arr = (int*)malloc(sizeof(int) * size); // 创建临时数组接收push的数据
int i = 0;
if(!QueueEmpty(&obj->push)){
while (!QueueEmpty(&obj->push)) {
arr[i++] = QueueFront(&obj->push);
QueuePop(&obj->push);
}
while (i--) {
QueuePush(&obj->pop, arr[i]); // 将数组接收push的数据 倒置插入 pop;
}
}
}
}
void myStackPush(MyStack* obj, int x) { // 入栈
QueuePush(&obj->push, x);
}
int myStackPop(MyStack* obj) { // 出栈,并返回原栈顶元素
if (myStackEmpty(obj))
return -1;
PushToPop(obj);
int ret = QueueFront(&obj->pop);
QueuePop(&obj->pop);
return ret;
}
int myStackTop(MyStack* obj) { // 返回原栈顶元素
if (myStackEmpty(obj))
return -1;
PushToPop(obj);
int ret =( QueueEmpty(&obj->push)?QueueFront(&obj->pop):QueueBack(&obj->push) );
return ret;
}
void myStackFree(MyStack* obj) {
QueueDestory(&obj->pop);
QueueDestory(&obj->push);
free(obj);
}
232. 用栈实现队列
// 定义两个栈,push存放入队数据,pop存放出队数据
// 每次出队,将push的数据 倒置存入 pop,pop再进行出栈就相当于 队列进行头删
//******************************************************** 栈的实现
typedef int STDataType;
typedef struct Stack{
int *_arr;
int _top;
int _capacity;
}Stack;
void StackInit(Stack* ps); // 初始化栈
void StackPush(Stack* ps, STDataType data); // 入栈
void StackPop(Stack* ps); // 出栈
STDataType StackTop(Stack* ps); // 获取栈顶元素
int StackSize(Stack* ps); // 获取栈中有效元素个数
int StackEmpty(Stack* ps); // 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
void StackDestroy(Stack* ps);// 销毁栈
// 初始化栈
void StackInit(Stack* ps) {
assert(ps);
ps->_arr = NULL;
ps->_capacity = ps->_top = 0;
}
// 入栈
void StackPush(Stack* ps, STDataType data) {
assert(ps);
if (ps->_top == ps->_capacity) {
int newCapacity = (ps->_capacity==0)?4:ps->_capacity*2;
STDataType* tmp = (STDataType*)realloc(ps->_arr,newCapacity * sizeof(STDataType));
if (tmp == NULL) {
perror("relloc fail");
exit(-1);
}
ps->_arr = tmp;
ps->_capacity = newCapacity;
}
ps->_arr[ps->_top] = data;
ps->_top++;
}
// 出栈
void StackPop(Stack* ps) {
assert(ps);
assert(!StackEmpty(ps));
ps->_top--;
}
// 获取栈顶元素
STDataType StackTop(Stack* ps) {
assert(ps);
assert(!StackEmpty(ps));
return ps->_arr[ps->_top - 1];
}
// 获取栈中有效元素个数
int StackSize(Stack* ps) {
assert(ps);
return ps->_top;
}
// 检测栈是否为空,如果为空返回非零结果,如果不为空返回0
int StackEmpty(Stack* ps) {
assert(ps);
return ps->_top == 0;
}
// 销毁栈
void StackDestroy(Stack* ps) {
assert(ps);
free(ps->_arr);
ps->_arr = NULL;
ps->_capacity = ps->_top = 0;
}
//******************************************************** 栈的实现
typedef struct {
Stack popst,pushst;
} MyQueue;
MyQueue* myQueueCreate() { // 初始化队列
MyQueue* obj=(MyQueue*)malloc(sizeof(MyQueue));
StackInit(&obj->popst);
StackInit(&obj->pushst);
return obj;
}
void PushToPop(MyQueue*obj){ // 将 push 倒入 pop
if( StackEmpty(&obj->popst) ){
while(!StackEmpty(&obj->pushst) ){
StackPush(&obj->popst,StackTop(&obj->pushst) );
StackPop(&obj->pushst);
}
}
}
void myQueuePush(MyQueue* obj, int x) { // 直接将数据存入 push。
StackPush(&obj->pushst,x);
}
int myQueuePop(MyQueue* obj) {
PushToPop(obj); // 判断是否需要倒置数据
int front=StackTop(&obj->popst);
StackPop(&obj->popst);
return front;
}
int myQueuePeek(MyQueue* obj) { // 返回队头数据
PushToPop(obj);
return StackTop(&obj->popst);
}
bool myQueueEmpty(MyQueue* obj) { // 判空
return (StackEmpty(&obj->popst)&&StackEmpty(&obj->pushst));
}
void myQueueFree(MyQueue* obj) {
StackDestroy(&obj->pushst);
StackDestroy(&obj->popst);
free(obj);
}
622. 设计循环队列
// 用循环单链表实现
typedef struct Node{
int val;
struct Node * next;
}Node;
typedef struct {
Node *head;
Node *tail;
int size;
int capacity;
} MyCircularQueue;
bool myCircularQueueIsEmpty(MyCircularQueue* obj) { // 判空 size 为 0 即为空
bool flag=false;
if(obj->size==0)
flag=true;
return flag;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {// 判满 size等于capacity 即为满
bool flag=false;
if(obj->size==obj->capacity)
flag=true;
return flag;
}
// 初始化循环队列
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue *obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
obj->capacity=k;
obj->size=0;
obj->head=NULL;
obj->tail=NULL;
Node*cur=NULL;
while(k--){ // 创建链表节点并一一链接
Node*newnode=(Node*)malloc(sizeof(Node));
if(cur==NULL&&obj->tail==NULL&&obj->head==NULL)
cur=obj->tail=obj->head=newnode;
else{
cur->next=newnode;
cur=cur->next;
}
}
cur->next=obj->head; // 将尾指针指向头,形成循环
return obj;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) { // 尾插
if (myCircularQueueIsFull(obj))
return false;
obj->tail->val = value;
obj->tail = obj->tail->next;
obj->size++;
return true;
}
// 头删。将头指针往后走一步,size-1,即相当于删除原来的头部数据
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return false;
obj->size--;
obj->head=obj->head->next;
return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {// 返回头部数据
if(myCircularQueueIsEmpty(obj))
return -1;
return obj->head->val;
}
// 返回尾部数据。该结构的设计导致取尾需要遍历,可以设计一个 last 记录最后一个数据的位置
// 或者设计容量为 k+1 的循环链表...
int myCircularQueueRear(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
return -1;
int n = obj->size;
Node* cur = obj->head;
while (n-->1) {
cur = cur->next;
}
return cur->val;
}
// 销毁
void myCircularQueueFree(MyCircularQueue* obj) {
int n=obj->capacity;
Node*cur=obj->head;
while(n--){
Node*next=cur->next;
free(cur);
cur=next;
}
obj->head=NULL;
obj->tail=NULL;
obj->size=0;
obj->capacity=0;
free(obj);
}