目录
1.循环队列
读过题后,我们很容易认为这道首选题链表,那么我们就以链表的思路分析一下:
首先明确一点就是这一块儿链表空间已经创建好了
我们用front和rear分别表示头和尾,那么我们知道初始状态front和rear指向同一个位置,那么不断插入数据rear不断后移,我们发现满的时候front和rear指向同一个位置,那么front和rear指向同一个位置是代表空还是满呢?
这里有两种方式解决,第一种是增加一个size判断空满;第二种是多开一个位置,在最后一个位置之后多开一个空位置,此时当rear和front相等时为空,当rear->next为front时为满。这个问题解决之后我们再看pop,连续的pop只需要让front往后移就可以,那么使用链表最难受的地方在于如何取尾,因为我们的rear指向的是尾的下一个,如果这里我们让rear指向尾,那么我们的初始化又会出问题,因为它会回到最初的front和rear指向同一个位置的空满问题上,当然这里解决方式有很多,比如添加一个prev指针指向front的前一个,或者使用双向链表等等......所以由此看出这道题用链表实际并不是最优解,正解是数组,当然数组思路大致也同上,我们选择多开一个位置,具体思路如下图所示:
那么我们接下来就完成这道题:
typedef struct {
int* a;
int front;
int rear;
int k;
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
obj->front =obj->rear =0;
obj->a =(int*)malloc(sizeof(int)*(k+1));
obj->k=k;
return obj;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->front==obj->rear;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->rear+1)%(obj->k+1)==obj->front;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if(myCircularQueueIsFull(obj))
return false;
obj->a[obj->rear++]=value;
obj->rear%=(obj->k+1);
return true;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return false;
++obj->front;
obj->front%=(obj->k+1);
return true;
}
int myCircularQueueFront(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return -1;
else
return obj->a[obj->front];
}
int myCircularQueueRear(MyCircularQueue* obj) {
if(myCircularQueueIsEmpty(obj))
return -1;
else
return obj->a[(obj->rear-1+obj->k+1)%(obj->k+1)];
}
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->a);
free(obj);
}
2.括号匹配
这道题我们的思路是如果是左括号,则入栈;如果是右括号,则出栈,将取出的左括号与该右括号匹配。比如如果我们给的是(([{}]))(),那么我们一开始都是左括号,都入栈,直到第一个右括号出现出栈一个左括号与之匹配,然后重复操作,直到下一个是左括号,则继续进栈,继续找与之匹配的右括号直到结束。
代码实现一下:当然这道题我们依然需要先把栈的结构给出
typedef char STDataType;
typedef struct Stack
{
STDataType* a;
int top;
int capacity;
}ST;
void STInit(ST* ps);//初始化
void STPush(ST* ps, STDataType x);//插入
void STPop(ST* ps);//删除
int STSize(ST* ps);//栈的大小
bool STEmpty(ST* ps);//判空
void STDestroy(ST* ps);//销毁
STDataType STTop(ST* ps);//访问栈顶元素
void STInit(ST* ps)
{
assert(ps);
ps->a = (STDataType*)malloc(sizeof(STDataType) * 4);
if (ps->a == NULL)
{
perror("malloc fail");
return;
}
ps->capacity = 4;
ps->top = 0;
}
void STDestroy(ST* ps)
{
assert(ps);
free(ps->a);
ps->a = NULL;
ps->top = 0;
ps->capacity = 0;
}
void STPush(ST* ps, STDataType x)
{
assert(ps);
if (ps->top == ps->capacity)
{
STDataType* tmp = (STDataType*)realloc(ps->a,sizeof(STDataType) * ps->capacity * 2);
if (ps->a == NULL)
{
perror("calloc fail");
return;
}
ps->a = tmp;
ps->capacity *= 2;
}
ps->a[ps->top] = x;
ps->top++;
}
bool STEmpty(ST* ps)
{
assert(ps);
return ps->top == 0;
}
void STPop(ST* ps)
{
assert(ps);
assert(!STEmpty(ps));
ps->top--;
}
int STSize(ST* ps)
{
assert(ps);
return ps->top;
}
STDataType STTop(ST* ps)
{
assert(ps);
assert(!STEmpty(ps));
return ps->a[ps->top - 1];
}
bool isValid(char * s){
ST st;
STInit(&st);
while(*s)
{
if(*s=='('||*s=='['||*s=='{')
{
STPush(&st,*s);
}
else
{
if(STEmpty(&st))
return false;
char top=STTop(&st);
STPop(&st);
if(*s==')'&&top!='(')
return false;
else if(*s==']'&&top!='[')
return false;
else if(*s=='}'&&top!='{')
return false;
}
++s;
}
bool ret = STEmpty(&st);
STDestroy(&st);
return ret;
}