数据结构学习笔记(栈队列OJ题)整体与总结
Posted 康x呀
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构学习笔记(栈队列OJ题)整体与总结相关的知识,希望对你有一定的参考价值。
1.括号匹配问题
OJ链接:[https://leetcode-cn.com/problems/valid-parentheses/]
题目:给定一个只包括 ‘(’,’)’,’{’,’}’,’[’,’]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
代码:
**思路**:共有两种方法,第一种方法就是写链出链栈,然后进行操作,另外一种方法就是用数组
模拟栈进行操作。在建立栈之后,将字符串函数依次放入栈中,栈顶元素与进入的元素匹配与
否然后返回true还是false。
// An highlighted block
//链栈
#define ElemType char
typedef struct LinkStackNode
{
ElemType data;
struct LinkStackNode *next;
}LinkStackNode;
typedef struct LinkStack
{
LinkStackNode *head;
}LinkStack;
void LinkStackInit(LinkStack *pst);
void LinkStackPush(LinkStack *pst, ElemType v);
void LinkStackPop(LinkStack *pst);
ElemType LinkStackTop(LinkStack *pst);
void LinkStackShow(LinkStack *pst);
void LinkStackDestroy(LinkStack *pst);
bool LinkStackEmpty(LinkStack *pst);
void LinkStackInit(LinkStack *pst)
{
pst->head = NULL;
}
void LinkStackPush(LinkStack *pst, ElemType v)
{
LinkStackNode *s = (LinkStackNode*)malloc(sizeof(LinkStackNode));
assert(s != NULL);
s->data = v;
s->next = pst->head;
pst->head = s;
}
void LinkStackPop(LinkStack *pst)
{
LinkStackNode *p;
if(pst->head == NULL)
return;
p = pst->head;
pst->head = p->next;
free(p);
}
ElemType LinkStackTop(LinkStack *pst)
{
assert(pst->head != NULL);
return pst->head->data;
}
void LinkStackShow(LinkStack *pst)
{
LinkStackNode *p = pst->head;
while(p != NULL)
{
printf("%d\\n", p->data);
p = p->next;
}
}
void LinkStackDestroy(LinkStack *pst)
{
LinkStackNode *p = pst->head;
while(p != NULL)
{
pst->head = p->next;
free(p);
p = pst->head;
}
}
bool LinkStackEmpty(LinkStack *pst)
{
return pst->head == NULL;
}
//
bool isValid(char * s)
{
if(s==NULL || *s=='\\0')
return true;
LinkStack st;
LinkStackInit(&st);
while(*s != '\\0')
{
if(*s=='{' || *s=='[' || *s=='(')
LinkStackPush(&st, *s);//上面需要定义为字符类型——#define ElemType char
else
{
if(LinkStackEmpty(&st))
return false;
char top_val = LinkStackTop(&st);
if( (*s=='}' && top_val!='{') ||
(*s==']' && top_val!='[') ||
(*s==')' && top_val!='(') )
return false;
LinkStackPop(&st);
}
s++;
}
if(LinkStackEmpty(&st))
return true;
return false;
}
//使用数组模拟栈
bool isValid(char * s)
{
if(s==NULL || *s=='\\0')
return true;
int len = strlen(s);
//开辟栈空间
char *st = (char*)malloc(sizeof(char) * len);
int top = 0; //栈顶指针
while(*s != '\\0')
{
if(*s=='{' || *s=='[' || *s=='(')
st[top++] = *s; //入栈
else
{
if(top == 0)
return false;
char top_val = st[top-1];
if( (*s=='}' && top_val!='{') ||
(*s==']' && top_val!='[') ||
(*s==')' && top_val!='(') )
return false;
top--;//出栈
}
s++;
}
free(st);
st = NULL;
if(top == 0)
return true;
return false;
}
2.用队列实现栈
OJ链接:[https://leetcode-cn.com/problems/implement-stack-using-queues/]
题目:请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。
**思路:**我们可以想到用两个队列,一个空队列,一个放数据,当我们入队的时候将数据直接
放入非空队列,出队的时候将非空队列中除队尾外的所有元素放到空队列中,再出队尾即可。
// An highlighted block
//链队列
#define ElemType int
typedef struct LinkQueueNode
{
ElemType data;
struct LinkQueueNode *link;
}LinkQueueNode;
typedef struct LinkQueue
{
LinkQueueNode *front;
LinkQueueNode *rear;
}LinkQueue;
void LinkQueueInit(LinkQueue *pq);
void LinkQueuePush(LinkQueue *pq, ElemType v);
void LinkQueuePop(LinkQueue *pq);
ElemType LinkQueueFront(LinkQueue *pq);
ElemType LinkQueueBack(LinkQueue *pq);
void LinkQueueShow(LinkQueue *pq);
bool LinkQueueEmpty(LinkQueue *pq);
void LinkQueueDestroy(LinkQueue *pq);
void LinkQueueInit(LinkQueue *pq)
{
pq->front = pq->rear = NULL;
}
void LinkQueuePush(LinkQueue *pq, ElemType v)
{
LinkQueueNode *s = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
assert(s != NULL);
s->data = v;
s->link = NULL;
if(pq->front == NULL)
pq->front = pq->rear = s;
else
{
pq->rear->link = s;
pq->rear = s;
}
}
void LinkQueuePop(LinkQueue *pq)
{
LinkQueueNode *p;
if(pq->front == NULL)
return;
p = pq->front;
pq->front = p->link;
free(p);
}
ElemType LinkQueueFront(LinkQueue *pq)
{
assert(pq->front != NULL);
return pq->front->data;
}
ElemType LinkQueueBack(LinkQueue *pq)
{
assert(pq->front != NULL);
return pq->rear->data;
}
void LinkQueueShow(LinkQueue *pq)
{
LinkQueueNode *p = pq->front;
while(p != NULL)
{
printf("%d ", p->data);
p = p->link;
}
printf("\\n");
}
bool LinkQueueEmpty(LinkQueue *pq)
{
return pq->front == NULL;
}
void LinkQueueDestroy(LinkQueue *pq)
{
while(pq->front != NULL)
{
LinkQueueNode *p = pq->front;
pq->front = p->link;
free(p);
}
pq->front = pq->rear = NULL;
}
typedef struct
{
LinkQueue q1;
LinkQueue q2;
} MyStack;
/** Initialize your data structure here. */
MyStack* myStackCreate()
{
MyStack *pst = (MyStack*)malloc(sizeof(MyStack));
LinkQueueInit(&(pst->q1));
LinkQueueInit(&(pst->q2));
return pst;
}
/** Push element x onto stack. */
void myStackPush(MyStack* obj, int x)
{
LinkQueue *pnoempty;
if(!LinkQueueEmpty(&(obj->q1)))
pnoempty = &(obj->q1);
else
pnoempty = &(obj->q2);
LinkQueuePush(pnoempty, x);
}
/** Removes the element on top of the stack and returns that element. */
int myStackPop(MyStack* obj)
{
LinkQueue *pnoempty, *pempty;
if(!LinkQueueEmpty(&(obj->q1)))
{
pnoempty = &(obj->q1);
pempty = &(obj->q2);
}
else
{
pnoempty = &(obj->q2);
pempty = &(obj->q1);
}
int val;
while(!LinkQueueEmpty(pnoempty))
{
val = LinkQueueFront(pnoempty);
LinkQueuePop(pnoempty);
if(LinkQueueEmpty(pnoempty))
break;
LinkQueuePush(pempty, val);
}
return val;
}
/** Get the top element. */
int myStackTop(MyStack* obj)
{
LinkQueue *pnoempty, *pempty;
if(!LinkQueueEmpty(&(obj->q1)))
{
pnoempty = &(obj->q1);
pempty = &(obj->q2);
}
else
{
pnoempty = &(obj->q2);
pempty = &(obj->q1);
}
int val;
while(!LinkQueueEmpty(pnoempty))
{
val = LinkQueueFront(pnoempty);
LinkQueuePop(pnoempty);
LinkQueuePush(pempty, val);
}
return val;
}
/** Returns whether the stack is empty. */
bool myStackEmpty(MyStack* obj)
{
return LinkQueueEmpty(&(obj->q1)) && LinkQueueEmpty(&(obj->q2));
}
void myStackFree(MyStack* obj)
{
LinkQueueDestroy(&(obj->q1));
LinkQueueDestroy(&(obj->q2));
free(obj);
}
3.用栈实现队列
OJ链接:https://leetcode-cn.com/problems/implement-queue-using-stacks/
题目:请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:
void push(int x) 将元素 x 推到队列的末尾
int pop() 从队列的开头移除并返回元素
int peek() 返回队列开头的元素
boolean empty() 如果队列为空,返回 true ;否则,返回 false
思路:建立两个栈,先将第一个栈内的所有元素入到第二个栈内(栈必须为空),然后将第二个栈
的所有元素出栈,如果还有元素继续按照上述操作继续即可。
// An highlighted block
//链栈
#define ElemType char
typedef struct LinkStackNode
{
ElemType data;
struct LinkStackNode *next;
}LinkStackNode;
typedef struct LinkStack
{
LinkStackNode *head;
}LinkStack;
void LinkStackInit(LinkStack *pst);
void LinkStackPush(LinkStack *pst, ElemType v);
void LinkStackPop(LinkStack *pst);
ElemType LinkStackTop(LinkStack *pst);
void LinkStackShow(LinkStack *pst);
void LinkStackDestroy(LinkStack *pst);
bool LinkStackEmpty(LinkStack *pst);
void LinkStackInit(LinkStack *pst)
{
pst->head = NULL;
}
void LinkStackPush(LinkStack *pst, ElemType v)
{
LinkStackNode *s = (LinkStackNode*)malloc(sizeof(LinkStackNode));
assert(s != NULL);
s->data = v;
s->next = pst->head;
pst->head = s;
}
void LinkStackPop(LinkStack *pst)
{
LinkStackNode *p;
if(pst->head == NULL)
return;
p = pst->head;
pst->head = p->next;
free(p);
}
ElemType LinkStackTop(LinkStack *pst)
{
assert(pst->head != NULL);
return pst->head->data;
}
void LinkStackShow(LinkStack *pst)
{
LinkStackNode *p = pst->head;
while(p != NULL)
{
printf("%d\\n", p->data);
p = p->next;
}
}
void LinkStackDestroy(LinkStack *pst)
{
LinkStackNode *p = pst->head;
while(p != NULL)
{
pst->head = p->next;
free(p);
p = pst->head;
}
}
bool LinkStackEmpty(LinkStack *pst)
{
return pst->head == NULL;
}
//
typedef struct
{
LinkStack st1;
LinkStack st2;
} MyQueue;
/** Initialize your data structure here. */
MyQueue* myQueueCreate()
{
MyQueue *pq = (MyQueue*)malloc(sizeof数据结构学习笔记(栈队列)整理与总结