赞
踩
链接: link
题目描述:
题目思路:
1、如果是左括号“( { [ ”就入栈
2、如果是右括号“) } ] ”,就取出栈顶元素与该右括号进行匹配
如果不匹配,就直接return false
如果匹配,s++,指针继续向下走,寻找下一个括号,进行上述操作
注意:
1、如果只有左括号,则栈不为空,则要return false
2、如果只有右括号,栈为空,不能取栈顶元素进行匹配
3、内存泄漏问题,每次返回一个bool值之前都要销毁栈,以免发生内存泄漏
代码实现:
typedef char STDataType; typedef struct Stack { STDataType* a; int top; int capacity; }ST; void STInit(ST* pst); void STDestroy(ST* pst); void STPush(ST* pst, STDataType x); void STPop(ST* pst); STDataType STTop(ST* pst); bool STEmpty(ST* pst); int STSize(ST* pst); void STInit(ST* pst) { assert(pst); pst->a = NULL;//最开始不malloc空间 //pst->top = -1;//指向栈顶元素 pst->top = 0;//指向栈顶元素的下一个位置,表示已经有元素 pst->capacity = 0; } void STDestroy(ST* pst) { assert(pst); free(pst->a); pst->a = NULL; pst->top = 0; pst->capacity = 0; } void STPush(ST* pst, STDataType x) { assert(pst); if (pst->top == pst->capacity) { int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2; STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * newcapacity); if (tmp == NULL) { perror("realloc fail"); return; } pst->a = tmp; pst->capacity = newcapacity; } pst->a[pst->top] = x; pst->top++; } void STPop(ST* pst) { assert(pst); assert(!STEmpty(pst)); pst->top--; } STDataType STTop(ST* pst) { assert(pst); assert(!STEmpty(pst)); return pst->a[pst->top - 1];//栈顶元素 } bool STEmpty(ST* pst) { return pst->top == 0; } int STSize(ST* pst) { assert(pst); return pst->top; } bool isValid(char * s) { ST st; STInit(&st); while(*s) { //1、左括号入栈 if(*s=='(' || *s=='{' || *s=='[') { STPush(&st,*s); } //2、右括号出栈匹配 else { //不匹配情况 //如果栈空,只有右括号,则不匹配,直接返回false if(STEmpty(&st)) { return false; } char top = STTop(&st); STPop(&st); if((*s==']'&&top!='[') || (*s=='}'&&top!='{') ||(*s==')'&&top!='(')) { return false; } //匹配 } s++;//向后遍历字符串寻找括号 } bool ret = STEmpty(&st);//如果栈空返回true,否则返回false STDestroy(&st); return ret; }
链接: link
题目描述:
题目思路:
两个栈实现队列,首先明确:
栈后进先出
队列先进先出
方法:
此处方法就是先倒数据,将栈1的元素4 3 2全部导入栈2中,最后删除1,如下图
在这个过程中,将栈1的全部元素导入栈2后,我们可以发现栈2出栈的顺序就是队列出队的顺序,于是可以将两个栈做如下更改:
分析:
1、队列的结构
typedef struct { ST pushst; ST popst; } MyQueue; MyQueue* myQueueCreate() { MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue)); if(obj==NULL) { perror("malloc fail"); return NULL; } STInit(&obj->pushst); STInit(&obj->popst); return obj; }
2、入队操作
此处入队操作就是入栈操作,将元素入到pushst栈当中
void myQueuePush(MyQueue* obj, int x)
{
STPush(&obj->pushst,x);
}
3、返回队列开头元素
首先判断popst中是否为空,如果popst为空,判断pushst是否为空,如果pushst不为空,将pushst中的元素入栈到popst中,最后返回popst的栈顶元素
int myQueuePeek(MyQueue* obj) //只取栈顶元素
{
if(STEmpty(&obj->popst))
{
while(!STEmpty(&obj->pushst))
{
STPush(&obj->popst,STTop(&obj->pushst));
STPop(&obj->pushst);
}
}
return STTop(&obj->popst);//popst中的栈顶元素,即pushst中的栈底元素
}
4、移除队列开头的元素,并返回队头元素
复用myQueuePeek函数,保存该函数的返回值,再出popst的栈顶元素
int myQueuePop(MyQueue* obj) //删数据
{
int front = myQueuePeek(obj);
STPop(&obj->popst);
return front;
}
5、判空
popst和pushst同时为空
bool myQueueEmpty(MyQueue* obj)
{
return STEmpty(&obj->pushst)&&STEmpty(&obj->popst);
}
6、销毁
void myQueueFree(MyQueue* obj)
{
STDestroy(&obj->pushst);
STDestroy(&obj->popst);
free(obj);
}
整体代码:
typedef int STDataType; typedef struct Stack { STDataType* a; int top; int capacity; }ST; void STInit(ST* pst); void STDestroy(ST* pst); void STPush(ST* pst, STDataType x); void STPop(ST* pst); STDataType STTop(ST* pst); bool STEmpty(ST* pst); int STSize(ST* pst); void STInit(ST* pst) { assert(pst); pst->a = NULL;//最开始不malloc空间 //pst->top = -1;//指向栈顶元素 pst->top = 0;//指向栈顶元素的下一个位置,表示已经有元素 pst->capacity = 0; } void STDestroy(ST* pst) { assert(pst); free(pst->a); pst->a = NULL; pst->top = 0; pst->capacity = 0; } void STPush(ST* pst, STDataType x) { assert(pst); if (pst->top == pst->capacity) { int newcapacity = pst->capacity == 0 ? 4 : pst->capacity * 2; STDataType* tmp = (STDataType*)realloc(pst->a, sizeof(STDataType) * newcapacity); if (tmp == NULL) { perror("realloc fail"); return; } pst->a = tmp; pst->capacity = newcapacity; } pst->a[pst->top] = x; pst->top++; } void STPop(ST* pst) { assert(pst); assert(!STEmpty(pst)); pst->top--; } STDataType STTop(ST* pst) { assert(pst); assert(!STEmpty(pst)); return pst->a[pst->top - 1];//栈顶元素 } bool STEmpty(ST* pst) { return pst->top == 0; } int STSize(ST* pst) { assert(pst); return pst->top; } typedef struct { ST pushst; ST popst; } MyQueue; MyQueue* myQueueCreate() { MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue)); if(obj==NULL) { perror("malloc fail"); return NULL; } STInit(&obj->pushst); STInit(&obj->popst); return obj; } void myQueuePush(MyQueue* obj, int x) { STPush(&obj->pushst,x); } int myQueuePop(MyQueue* obj) //删数据 { int front = myQueuePeek(obj); STPop(&obj->popst); return front; } int myQueuePeek(MyQueue* obj) //只取栈顶元素 { if(STEmpty(&obj->popst)) { while(!STEmpty(&obj->pushst)) { STPush(&obj->popst,STTop(&obj->pushst)); STPop(&obj->pushst); } } return STTop(&obj->popst);//popst中的栈顶元素,即pushst中的栈底元素 } bool myQueueEmpty(MyQueue* obj) { return STEmpty(&obj->pushst)&&STEmpty(&obj->popst); } void myQueueFree(MyQueue* obj) { STDestroy(&obj->pushst); STDestroy(&obj->popst); free(obj); }
链接: link
题目描述:
题目思路:
题目中给我们两个队列实现一个栈,首先明确:
1、队列的性质:先进先出
2、栈的性质:后进先出
如何才能使用两个队列实现栈的后进先出?
本题给的两个队列就是用来导数据,进而实现栈的后进先出的性质
举例:如上图,如果说我们要出数据5,那么就需要将队列1当中的1 2 3 4 先入到队列2中,再出数据5,这样就实现了后进先出的性质。
注意:
如何入数据?
1、如果两个队列中的一个队列为空一个队列不为空,那么数据入到非空队列中
2、如果两个队列都为空,数据入到其中一个队列
分析:
1、栈的结构和栈的创建
方法1:给定MyStack栈中的两个队列都是结构体类型,直接malloc动态开辟一个栈的空间,里面存放队列1 q1和队列2 q2
初始化队列使用结构体指针。
方法2:给定MyStack栈中的两个队列都是结构体指针类型,动态开辟栈的空间,再动态开辟队列的空间,这样在初始化时就不需要进行取地址操作,因为q1和q2就是结构体指针类型。
2、入数据操作
1、如果q1不为空,那么就入队列1中
2、如果q2不为空,那么就入队列2中
3、如果两个都不为空,则随意入队列
void myStackPush(MyStack* obj, int x)
{
if(!QueueEmpty(&obj->q1))
{
QueuePush(&obj->q1,x);
}
else
{
QueuePush(&obj->q2,x);
}
}
3、出栈操作——倒数据
1、将非空队列的队头的数据导入空队列当中——入队
2、弹出非空队列的队头数据
3、取栈顶元素
int myStackPop(MyStack* obj) { Queue* qEmpty=&obj->q1; Queue* qNoneEmpty = &obj->q2; if(!QueueEmpty(&obj->q1)) { Queue* qEmpty=&obj->q2; Queue* qNoneEmpty = &obj->q1; } while(QueueSize(qNoneEmpty)>1) { QueuePush(qEmpty,QueueFront(qNoneEmpty)); QueuePop(qNoneEmpty); } int top = QueueFront(qNoneEmpty); QueuePop(qNoneEmpty); return top; }
4、取栈顶元素——队尾元素
1、第一个队列不为空,就取队尾元素
2、反之取第二个队列的队尾元素
int myStackTop(MyStack* obj)
{
if(!QueueEmpty(&obj->q1))
{
return QueueBack(&obj->q1);
}
else
{
return QueueBack(&obj->q2);
}
}
5、判空
bool myStackEmpty(MyStack* obj)
{
return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2);
}
6、销毁
不仅释放栈,也要释放队列
void myStackFree(MyStack* obj)
{
QueueDestroy(&obj->q1);
QueueDestroy(&obj->q2);
free(obj);
}
整体代码:
typedef int QDataType; //每个节点的结构 typedef struct QueueNode { QDataType data; struct QueueNode* next; }QNode; //标识整个队列的结构 typedef struct Queue { QNode* phead; QNode* ptail; int size;//队列的长度 }Queue; void QueueInit(Queue* pq); void QueueDestroy(Queue* pq); void QueuePush(Queue* pq, QDataType x); void QueuePop(Queue* pq); QDataType QueueFront(Queue* pq); QDataType QueueBack(Queue* pq); int QueueSize(Queue* pq); bool QueueEmpty(Queue* pq); void QueueInit(Queue* pq) { assert(pq); pq->phead = NULL; pq->ptail = NULL; pq->size = 0; } void QueueDestroy(Queue* pq) { assert(pq); QNode* cur = pq->phead; while (cur) { QNode* next = cur->next; free(cur); cur = next; } pq->phead = pq->ptail = NULL; pq->size = 0; } void QueuePush(Queue* pq, QDataType x) { assert(pq); QNode* newnode = (QNode*)malloc(sizeof(QNode)); if (newnode == NULL) { perror("malloc fail"); return; } newnode->data = x; newnode->next = NULL; //队列为空 if (pq->ptail == NULL) { assert(pq->phead == NULL); pq->phead = pq->ptail = newnode; } else { //队列不空 pq->ptail->next = newnode; pq->ptail = newnode; } pq->size++; } void QueuePop(Queue* pq) { //类似头删 assert(pq); assert(!QueueEmpty(pq)); //1、一个节点 //2、多个节点 if (pq->phead->next == NULL) { free(pq->phead); pq->phead = pq->ptail = NULL; } else { //头删 QNode* next = pq->phead->next; free(pq->phead); pq->phead = next; } pq->size--; } QDataType QueueFront(Queue* pq) { assert(pq); assert(!QueueEmpty(pq)); return pq->phead->data; } QDataType QueueBack(Queue* pq) { assert(pq); assert(!QueueEmpty(pq)); return pq->ptail->data; } int QueueSize(Queue* pq) { assert(pq); return pq->size; } bool QueueEmpty(Queue* pq) { assert(pq); //return pq->size == 0; return pq->phead == NULL && pq->ptail == NULL; } typedef struct { Queue q1;//队列1 Queue q2;//队列2 } MyStack; MyStack* myStackCreate() { MyStack* obj = (MyStack*)malloc(sizeof(MyStack)); if (obj == NULL) { perror("malloc fail"); return NULL; } QueueInit(&obj->q1); QueueInit(&obj->q2); return obj; } void myStackPush(MyStack* obj, int x) { if(!QueueEmpty(&obj->q1)) { QueuePush(&obj->q1,x); } else { QueuePush(&obj->q2,x); } } int myStackPop(MyStack* obj) { Queue* qEmpty=&obj->q1; Queue* qNoneEmpty = &obj->q2; if(!QueueEmpty(&obj->q1)) { qEmpty=&obj->q2; qNoneEmpty = &obj->q1; } while(QueueSize(qNoneEmpty)>1) { QueuePush(qEmpty,QueueFront(qNoneEmpty)); QueuePop(qNoneEmpty); } int top = QueueFront(qNoneEmpty); QueuePop(qNoneEmpty); return top; } int myStackTop(MyStack* obj) { if(!QueueEmpty(&obj->q1)) { return QueueBack(&obj->q1); } else { return QueueBack(&obj->q2); } } bool myStackEmpty(MyStack* obj) { return QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2); } void myStackFree(MyStack* obj) { QueueDestroy(&obj->q1); QueueDestroy(&obj->q2); free(obj); }
链接: link
题目描述:
思路分析:
本题使用数组设计循环队列
1、假设循环队列存储k个数据,开k+1个空间,每次入队一个元素,rear指针都会指向该元素的后一个位置。
1、循环队列的结构
typedef struct { int front; int rear; int k;//队列中元素个数 int* a; } MyCircularQueue; MyCircularQueue* myCircularQueueCreate(int k) { MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue)); obj->a = (int*)malloc(sizeof(int*)*(k+1)); obj->front=obj->rear = 0; obj->k=0; return obj; }
2、判断循环队列为空:front=rear
bool myCircularQueueIsEmpty(MyCircularQueue* obj)
{
return obj->rear==obj->front;
}
3、判断队列满:(rear+1)%(k+1)==front
bool myCircularQueueIsFull(MyCircularQueue* obj)
{
return (obj->rear+1)%(obj->k+1)==obj->front;
}
4、入数据
在rear位置入数据再让rear++,特殊情况:循环队列可能会绕回去,所以要判断rear的位置
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{
if( myCircularQueueIsEmpty(obj))
{
return false;
}
obj->a[obj->rear]=value;
obj->rear++;
obj->rear%=(obj->k+1);//保证范围
}
5、出数据(删除数据)
判空,如果为空,则不进行删除操作
删除操作即让front++,并且保证front的范围
bool myCircularQueueDeQueue(MyCircularQueue* obj)
{
if( myCircularQueueIsEmpty(obj))
{
return false;
}
obj->front++;
obj->front%=(obj->k+1);//保证范围
return true;
}
6、返回队头和队尾数据
int myCircularQueueFront(MyCircularQueue* obj) { if(myCircularQueueIsEmpty(obj)) { return -1; } return obj->a[obj->front]; } int myCircularQueueRear(MyCircularQueue* obj) { if(myCircularQueueIsEmpty(obj)) { return -1; } else if(obj->rear==0) { return obj->a[obj->rear+k-1]; } else { return obj->a[obj->rear-1]; } }
整体代码:
typedef struct { int front; int rear; int k;//队列中元素个数 int* a; } MyCircularQueue; bool myCircularQueueIsEmpty(MyCircularQueue* obj) { return obj->rear==obj->front; } bool myCircularQueueIsFull(MyCircularQueue* obj) { return (obj->rear+1)%(obj->k+1)==obj->front; } MyCircularQueue* myCircularQueueCreate(int k) { MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue)); obj->a = (int*)malloc(sizeof(int)*(k+1)); obj->front=obj->rear = 0; obj->k=k; return obj; } bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) { if( myCircularQueueIsFull(obj)) { return false; } obj->a[obj->rear]=value; obj->rear++; 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; } return obj->a[obj->front]; } int myCircularQueueRear(MyCircularQueue* obj) { if(myCircularQueueIsEmpty(obj)) { return -1; } return obj->a[(obj->rear+obj->k)%(obj->k+1)]; } void myCircularQueueFree(MyCircularQueue* obj) { free(obj->a); free(obj); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。