【数据结构】栈和队列

栈和队列的相关题目

  • 循环队列
  • 用队列实现栈
  • 用栈实现队列
  • 括号匹配
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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值