数据结构学习笔记(栈队列OJ题)整体与总结

Posted 康x呀

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构学习笔记(栈队列OJ题)整体与总结相关的知识,希望对你有一定的参考价值。

数据结构学习笔记(栈、队列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数据结构学习笔记(栈队列)整理与总结

数据结构学习笔记(栈队列)整理与总结

数据结构学习笔记(二叉树)OJ题总结与整理

数据结构学习笔记(二叉树)OJ题总结与整理

数据结构学习笔记(数组链表OJ题)整理与总结

数据结构学习笔记(数组链表OJ题)整理与总结