1.有效的括号【https://leetcode-cn.com/problems/valid-parentheses/】
利用栈解决问题,如果遇到括号的右边直接进行入栈;如果遇到左边的括号,取栈顶元素与之进行匹配,如果匹配成功让栈顶元素出栈,如果匹配不成功返回false;最后在判断完字符串中的所有元素后,如果栈为空返回true,否则返回false完成判断。
//栈的实现
#define LinkStackElemType char
typedef struct LinkStackNode
{
LinkStackElemType data;
struct LinkStackNode *link;
}LinkStackNode;
typedef struct LinkStack
{
LinkStackNode *head;
}LinkStack;
void LinkStackInit(LinkStack *pst);
void LinkStackPush(LinkStack *pst, LinkStackElemType v);
void LinkStackPop(LinkStack *pst);
LinkStackElemType LinkStackTop(LinkStack *pst);
void LinkStackShow(LinkStack *pst);
bool LinkStackEmpty(LinkStack *pst)
{
assert(pst != NULL);
return pst->head == NULL;
}
void LinkStackInit(LinkStack *pst)
{
assert(pst != NULL);
pst->head = NULL;
}
void LinkStackPush(LinkStack *pst, LinkStackElemType v)
{
assert(pst != NULL);
LinkStackNode *s = (LinkStackNode*)malloc(sizeof(LinkStackNode));
assert(s != NULL);
s->data = v;
//把节点头插
s->link = pst->head;
pst->head = s;
}
void LinkStackPop(LinkStack *pst)
{
assert(pst != NULL);
if(LinkStackEmpty(pst))
{
printf("栈已空,不能出栈.\n");
return;
}
LinkStackNode *p = pst->head;
pst->head = p->link;
}
LinkStackElemType LinkStackTop(LinkStack *pst)
{
assert(pst != NULL);
if(LinkStackEmpty(pst))
{
printf("栈已空,不能取栈顶元素.\n");
return;
}
return pst->head->data;
}
void LinkStackShow(LinkStack *pst)
{
assert(pst != NULL);
LinkStackNode *p = pst->head;
while(p != NULL)
{
printf("%d\n", p->data);
p = p->link;
}
}
/
bool isValid(char * s){
assert(s!=NULL);
LinkStack pst;
LinkStackInit(&pst);
while(*s!='\0')
{
if(*s=='('||*s=='['||*s=='{')
LinkStackPush(&pst,*s);
else
{
if(LinkStackEmpty(&pst))
return false;
char a=LinkStackTop(&pst);
if((a=='('&&*s==')')||(a=='['&&*s==']')||(a=='{'&&*s=='}'))
LinkStackPop(&pst);
else
return false;
}
s++;
}
if(LinkStackEmpty(&pst))
return true;
return false;
}
2.用队列实现栈 【https://leetcode-cn.com/problems/implement-stack-using-queues/】
用队列实现栈至少需要两个队列,入栈时需要找出为空的队列进行入队即入栈;出栈时需要分别找出为空的队列和不为空的队列,将不为空的队列中的元素进行出队,将出队的元素在为空的队列中进行入队,最后一个元素不进行入队,完成了出栈。
//队列实现
#define LinkQueueElemType int
typedef struct LinkQueueNode
{
LinkQueueElemType data;
struct LinkQueueNode *link;
}LinkQueueNode;
typedef struct LinkQueue
{
LinkQueueNode *front;
LinkQueueNode *rear;
}LinkQueue;
bool LinkQueueEmpty(LinkQueue *pq)
{
assert(pq != NULL);
return pq->front == NULL;
}
void LinkQueueInit(LinkQueue *pq);
void LinkQueuePush(LinkQueue *pq, LinkQueueElemType v);
void LinkQueuePop(LinkQueue *pq);
void LinkQueueShow(LinkQueue *pq);
LinkQueueElemType LinkQueueFront(LinkQueue *pq);
LinkQueueElemType LinkQueueBack(LinkQueue *pq);
/
void LinkQueueInit(LinkQueue *pq)
{
assert(pq != NULL);
pq->front = pq->rear = NULL;
}
void LinkQueuePush(LinkQueue *pq, LinkQueueElemType v)
{
assert(pq != NULL);
LinkQueueNode *s = (LinkQueueNode*)malloc(sizeof(LinkQueueNode));
assert(s != NULL);
s->data = v;
s->link = NULL;
if(pq->rear == NULL)
pq->front = pq->rear = s;
else
{
pq->rear->link = s;
pq->rear = s;
}
}
void LinkQueuePop(LinkQueue *pq)
{
assert(pq != NULL);
if(LinkQueueEmpty(pq))
{
printf("队列已空,不能出队.\n");
return;
}
LinkQueueNode *p = pq->front;
if(pq->front == pq->rear)
pq->rear = NULL;
pq->front = p->link;
free(p);
}
void LinkQueueShow(LinkQueue *pq)
{
assert(pq != NULL);
LinkQueueNode *p = pq->front;
while(p != NULL)
{
printf("%d ", p->data);
p = p->link;
}
printf("\n");
}
LinkQueueElemType LinkQueueFront(LinkQueue *pq)
{
assert(pq != NULL);
assert(!LinkQueueEmpty(pq));
return pq->front->data;
}
LinkQueueElemType LinkQueueBack(LinkQueue *pq)
{
assert(pq != NULL);
assert(!LinkQueueEmpty(pq));
return pq->rear->data;
}
//
//用队列实现栈
typedef struct {
LinkQueue q1;
LinkQueue q2;
} MyStack;
MyStack* myStackCreate() {
MyStack* pst=(MyStack*)malloc(sizeof(MyStack));
LinkQueueInit(&pst->q1);
LinkQueueInit(&pst->q2);
return pst;
}
void myStackPush(MyStack* obj, int x) {
LinkQueue *noempty;
if(LinkQueueEmpty(&obj->q1))
noempty=&obj->q2;
if(LinkQueueEmpty(&obj->q2))
noempty=&obj->q1;
LinkQueuePush(noempty,x);
}
int myStackPop(MyStack* obj) {
LinkQueue *noempty,*empty;
int val;
if(LinkQueueEmpty(&obj->q1))
{
noempty=&obj->q2;
empty=&obj->q1;
}
if(LinkQueueEmpty(&obj->q2))
{
noempty=&obj->q1;
empty=&obj->q2;
}
while(!LinkQueueEmpty(noempty))
{
val=LinkQueueFront(noempty);
LinkQueuePop(noempty);
if(!LinkQueueEmpty(noempty))
LinkQueuePush(empty,val);
}
return val;
}
int myStackTop(MyStack* obj) {
LinkQueue *noempty,*empty;
int val;
if(LinkQueueEmpty(&obj->q1))
{
noempty=&obj->q2;
empty=&obj->q1;
}
if(LinkQueueEmpty(&obj->q2))
{
noempty=&obj->q1;
empty=&obj->q2;
}
while(!LinkQueueEmpty(noempty))
{
val=LinkQueueFront(noempty);
LinkQueuePop(noempty);
LinkQueuePush(empty,val);
}
return val;
}
bool myStackEmpty(MyStack* obj) {
return LinkQueueEmpty(&obj->q1)&&LinkQueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj) {
free(obj);
}
3.用栈实现队列【https://leetcode-cn.com/problems/implement-queue-using-stacks/】
用栈实现队列,至少需要两个栈来完成。用栈1只进行入队操作即对栈1进行元素入栈;要进行出队时,将栈1中的元素出栈,在栈2中进行入栈,最后将栈2中栈顶的元素进行出栈,达到了出队的效果。
//栈实现
#define LinkStackElemType int
typedef struct LinkStackNode
{
LinkStackElemType data;
struct LinkStackNode *link;
}LinkStackNode;
typedef struct LinkStack
{
LinkStackNode *head;
}LinkStack;
void LinkStackInit(LinkStack *pst);
void LinkStackPush(LinkStack *pst, LinkStackElemType v);
void LinkStackPop(LinkStack *pst);
LinkStackElemType LinkStackTop(LinkStack *pst);
void LinkStackShow(LinkStack *pst);
bool LinkStackEmpty(LinkStack *pst)
{
assert(pst != NULL);
return pst->head == NULL;
}
void LinkStackInit(LinkStack *pst)
{
assert(pst != NULL);
pst->head = NULL;
}
void LinkStackPush(LinkStack *pst, LinkStackElemType v)
{
assert(pst != NULL);
LinkStackNode *s = (LinkStackNode*)malloc(sizeof(LinkStackNode));
assert(s != NULL);
s->data = v;
//把节点头插
s->link = pst->head;
pst->head = s;
}
void LinkStackPop(LinkStack *pst)
{
assert(pst != NULL);
if(LinkStackEmpty(pst))
{
printf("栈已空,不能出栈.\n");
return;
}
LinkStackNode *p = pst->head;
pst->head = p->link;
}
LinkStackElemType LinkStackTop(LinkStack *pst)
{
assert(pst != NULL);
if(LinkStackEmpty(pst))
{
printf("栈已空,不能取栈顶元素.\n");
return;
}
return pst->head->data;
}
void LinkStackShow(LinkStack *pst)
{
assert(pst != NULL);
LinkStackNode *p = pst->head;
while(p != NULL)
{
printf("%d\n", p->data);
p = p->link;
}
}
//用栈实现队列
typedef struct {
LinkStack q1;
LinkStack q2;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue *pq=(MyQueue*)malloc(sizeof(MyQueue));
LinkStackInit(&pq->q1);
LinkStackInit(&pq->q2);
return pq;
}
bool myQueueEmpty(MyQueue* obj) {
if(LinkStackEmpty(&obj->q1)&&LinkStackEmpty(&obj->q2))
return true;
return false;
}
void myQueuePush(MyQueue* obj, int x) {
LinkStackPush(&obj->q1,x);
}
int myQueuePop(MyQueue* obj) {
int val;
if(LinkStackEmpty(&obj->q2))
{
while(!LinkStackEmpty(&obj->q1))
{
val=LinkStackTop(&obj->q1);
LinkStackPop(&obj->q1);
LinkStackPush(&obj->q2,val);
}
}
val=LinkStackTop(&obj->q2);
LinkStackPop(&obj->q2);
return val;
}
int myQueuePeek(MyQueue* obj) {
int val;
if(LinkStackEmpty(&obj->q2))
{
while(!LinkStackEmpty(&obj->q1))
{
val=LinkStackTop(&obj->q1);
LinkStackPop(&obj->q1);
LinkStackPush(&obj->q2,val);
}
}
val=LinkStackTop(&obj->q2);
return val;
}
void myQueueFree(MyQueue* obj) {
free(obj);
}
4设计循环队列【https://leetcode-cn.com/problems/design-circular-queue/】
设计循环队列主要在于让数组下标循环起来。front首元素下标,rear尾元素的下一个元素的坐标(此时未存放元素),capacity空间大小。判满条件(obj->rear+1)%obj->capacity==obj->front(obj为该队列)。判空条件obj->front==obj->rear。进行入队时第一步放入数据obj->base[obj->rear]=value; 第二部尾指针rear(在这里就是数组尾元素下标)指向下一个元素位置obj->rear=(obj->rear+1)%obj->capacity;。进行出队时头指针front(在这里就是数组首元素下标)指向下一个位置obj->front=(obj->front+1)%obj->capacity;。
//循环队列的实现
typedef struct {
int *base;//数组首元素地址
int front;
int rear;
int capacity;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue *pq=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
pq->base = (int*)malloc(sizeof(int) * (k+1));
pq->front=pq->rear=0;
pq->capacity=k+1;
return pq;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->front==obj->rear;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return ((obj->rear+1)%obj->capacity==obj->front);
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if(myCircularQueueIsFull(obj))
return false;
obj->base[obj->rear]=value;
obj->rear=(obj->rear+1)%obj->capacity;
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return false;
obj->front=(obj->front+1)%obj->capacity;
return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return -1;
return obj->base[obj->front];
}
int myCircularQueueRear(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return -1;
return obj->base[(obj->rear-1+obj->capacity)%obj->capacity];
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->base);
free(obj);
}