网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
首先将所给的字符串进行遍历,如果是左括号就将它压入栈中,根据栈后进先出的特性,然后逐个取出栈中的左括号与后面剩下的右括号进行逐对进行匹配,如果不匹配就返回false,如果都匹配了就返回true。
例如:
代码:
typedef char STDataType;
typedef struct Stack
{
STDataType* a;
int top;//栈顶的位置
int capacity;//容量
}ST;
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
void StackDestory(ST*ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity =ps->top = 0;
}
void StackPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)//满了进行扩容
{
int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
ps->a = (STDataType*)realloc(ps->a,sizeof(STDataType)*newCapacity);
if (ps->a == NULL)
{
printf("fail malloc\n");
exit(-1);
}
ps->capacity = newCapacity;
}
ps->a[ps->top++] = x;
}
void StackPop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
--ps->top;
}
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
STDataType StackTop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
return ps->a[ps->top - 1];
}
int SizeStack(ST* ps)
{
assert(ps);
return ps->top;
}
//前面的所有代码就是定义一个栈以及栈的相关函数
bool isValid(char * s){
ST st;
StackInit(&st);
while(*s)
{
if(*s=='['||*s=='('||*s=='{')
{
StackPush(&st,*s);
++s;
}
else
{
if(StackEmpty(&st))//当所给的字符串中只有右括号时直接返回false
{
StackDestory(&st);
return false;
}
char top = StackTop(&st);//从栈中取一个左括号
StackPop(&st);//进行出栈操作,让刚才取的字符出栈
if((*s==']'&&top!='[')
||(*s=='}'&&top!='{')
||(*s==')'&&top!='('))//两个字符不相匹配的情况下直接返回false
{
StackDestory(&st);
return false;
}
else
{
++s;
}
}
}
//栈为空,说明所有左括号都匹配了
bool ret = StackEmpty(&st);//判断是否只有左括号,如果只有左括号此时ret就为false,如果前面都已经匹配完了ret就等于true
StackDestory(&st);
return ret;
}
1.2 用队列实现栈
解析上面的实例:
输入的第一行是执行的操作。第二行是执行操作的数据。
输出是对应的返回值。
思路:用两个队列实现栈。
栈的基本结构:
1、入栈,push数据到不为空的队列。
2、出栈,把不为空的队列的数据前N-1导入到另一个空队列,最后剩下的一个删掉。
代码:
typedef int QDataType;
typedef struct QueueNode
{
QDataType data;
struct QueueNode* next;
}QNode;
typedef struct Queue
{
QNode* head;
QNode* tail;
}Queue;
void QueueInit(Queue* pq);
void QueueDestory(Queue* pq);
void QueuePush(Queue*pq,QDataType x);
void QueuePop(Queue*pq);
size_t QueueSize(Queue* pq);
QDataType QueueFront(Queue* pq);
QDataType QueueBack(Queue* pq);
bool QueueEmpty(Queue* pq);
void QueueInit(Queue* pq)
{
assert(pq);
pq->head =pq->tail = NULL;
}
QNode* BuyQNode(QDataType x)
{
QNode* newnode = (QNode*)malloc(sizeof(QNode));
if (newnode == NULL)
{
printf("fail malloc\n");
exit(-1);
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
void QueuePush(Queue* pq, QDataType x)
{
assert(pq);
QNode* newnode = BuyQNode(x);
if (pq->tail == NULL)
{
assert(pq->head == NULL);
pq->head= pq->tail = newnode;
}
else
{
pq->tail->next = newnode;
pq->tail = newnode;
}
}
void QueuePop(Queue* pq)
{
assert(pq);
assert(pq->tail&&pq->head);
if (pq->head->next==NULL)//处理只有一个节点的时候
{
free(pq->tail);
pq->tail = pq->head = NULL;
}
else//有多个节点
{
QNode* next = pq->head->next;
free(pq->head);
pq->head = next;
}
}
size_t QueueSize(Queue* pq)
{
assert(pq);
size_t size = 0;
QNode* cur = pq->head;
while (cur!= pq->tail->next)
{
size++;
cur = cur->next;
}
return size;
}
QDataType QueueFront(Queue* pq)
{
assert(pq);
assert(pq->head);
return pq->head->data;
}
QDataType QueueBack(Queue* pq)
{
assert(pq);
assert(pq->tail);
return pq->tail->data;
}
void QueueDestory(Queue* pq)
{
assert(pq);
QNode* cur = pq->head;
while (cur)
{
QNode* next = cur->next;
free(cur);
cur = next;
}
pq->head = pq->tail = NULL;
}
bool QueueEmpty(Queue* pq)
{
assert(pq);
return pq->head==NULL&&pq->tail==NULL;
}
typedef struct {
Queue q1;
Queue q2;
} MyStack;
MyStack* myStackCreate() {
MyStack* pst = (MyStack*)malloc(sizeof(MyStack));
assert(pst);
QueueInit(&pst->q1);//这一行代码和后面这一行代码等价:QueueInit(&(pst->q1));
QueueInit(&pst->q2);//这一行代码和后面这一行代码等价:QueueInit(&(pst->q2));
return pst;
}
void myStackPush(MyStack* obj, int x) {
assert(obj);
if(!QueueEmpty(&obj->q1))
{
QueuePush(&obj->q1,x);
}
else
{
QueuePush(&obj->q2,x);
}
}
int myStackPop(MyStack* obj) {
assert(obj);
Queue *emptyQ = &obj->q1;
Queue*nonEmptyQ = &obj->q2;
if(!QueueEmpty(&obj->q1))
{
emptyQ = &obj->q2;
nonEmptyQ = &obj->q1;
}
//把非空队列的前N个数据,导入空队列,剩下一个删掉
//就实现了后进先出
while(QueueSize(nonEmptyQ)>1)
{
QueuePush(emptyQ,QueueFront(nonEmptyQ));//将非空队列的队头数据push到非空队列中
QueuePop(nonEmptyQ);//将非空队列的队头数据出队
}
QDataType top = QueueFront(nonEmptyQ);
QueuePop(nonEmptyQ);
return top;
}
int myStackTop(MyStack* obj) {
assert(obj);
if(!QueueEmpty(&obj->q1))
{
return QueueBack(&obj->q1);
}
else
{
return QueueBack(&obj->q2);
}
}
bool myStackEmpty(MyStack* obj) {
assert(obj);
return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}
void myStackFree(MyStack* obj) {
assert(obj);
QueueDestory(&obj->q1);
QueueDestory(&obj->q2);
free(obj);
}
1.3 用栈实现队列
思路:
注意:在上面的代码中,在进行出队操作时,只要popST这个栈中有数据,那么我们就不进行倒数据的操作(即将push中的数据倒到popST这个栈中),只有当pop中的数据为空且我们要进行出队时才进行倒数据。
队列结构:
代码:
typedef int STDataType;
//数组栈的实现
typedef struct Stack
{
STDataType* a;
int top;//栈顶的位置
int capacity;//容量
}ST;
void StackInit(ST* ps)
{
assert(ps);
ps->a = NULL;
ps->capacity = 0;
ps->top = 0;
}
void StackDestory(ST*ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->capacity =ps->top = 0;
}
void StackPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)//满了进行扩容
{
int newCapacity = ps->capacity == 0 ? 2 : 2 * ps->capacity;
STDataType*new = (STDataType*)realloc(ps->a,sizeof(STDataType)*newCapacity);
if (new == NULL)
{
printf("fail malloc\n");
exit(-1);
}
ps->a = new;
ps->capacity = newCapacity;
}
ps->a[ps->top++] = x;
}
void StackPop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
--ps->top;
}
bool StackEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
STDataType StackTop(ST* ps)
{
assert(ps);
assert(ps->top > 0);
return ps->a[ps->top - 1];
}
int SizeStack(ST* ps)
{
assert(ps);
return ps->top;
}
void StackInit(ST*ps);
void StackDestory(ST* ps);
void StackPush(ST* ps,STDataType x);
void StackPop(ST* ps);
bool StackEmpty(ST* ps);
int SizeStack(ST* ps);
STDataType StackTop(ST* ps);
typedef struct {
ST pushST;
ST popST;
} MyQueue;
MyQueue* myQueueCreate() {
MyQueue * myQueue = (MyQueue*)malloc(sizeof(MyQueue));
assert(myQueue);
StackInit(&myQueue->pushST);
StackInit(&myQueue->popST);
return myQueue;
}
void myQueuePush(MyQueue* obj, int x) {
assert(obj);
StackPush(&obj->pushST,x);//入队直接向pushST插入即可
}
int myQueuePop(MyQueue* obj){
assert(obj);
if(StackEmpty(&obj->popST))//push为空,就进行倒数据,就符合先进先出的顺序了
{
while(!StackEmpty(&obj->pushST))
{
StackPush(&obj->popST,StackTop(&obj->pushST));
StackPop(&obj->pushST);
}
}
STDataType ret = StackTop(&obj->popST);//临时保存返回的数据
StackPop(&obj->popST);
return ret;
}
int myQueuePeek(MyQueue* obj) {
assert(obj);
if(StackEmpty(&obj->popST))
{
while(!StackEmpty(&obj->pushST))
{
StackPush(&obj->popST,StackTop(&obj->pushST));
StackPop(&obj->pushST);
}
}
return StackTop(&obj->popST);
}
bool myQueueEmpty(MyQueue* obj) {
assert(obj);
return StackEmpty(&obj->pushST)&&StackEmpty(&obj->popST);
}
void myQueueFree(MyQueue* obj) {
![img](https://img-blog.csdnimg.cn/img_convert/820139a4bdc2d1add97381407ae672e4.png)
![img](https://img-blog.csdnimg.cn/img_convert/9c35e064bdc38b56fdc65b3c38b012c5.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
&obj->popST);
}
bool myQueueEmpty(MyQueue* obj) {
assert(obj);
return StackEmpty(&obj->pushST)&&StackEmpty(&obj->popST);
}
void myQueueFree(MyQueue* obj) {
[外链图片转存中...(img-1Pvp7XD3-1715561667156)]
[外链图片转存中...(img-B5hGIZem-1715561667156)]
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618668825)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**