1.贴题目:
2.贴代码:
/* 两个栈实现队列, S1,S2,S1只管进,S2只管出*/
/* 入队操作: push元素进入S1 */
/* 出队操作: S2非空时, 从S2弹出元素, S2为空, S1数据导入S2再弹出 */
#define MAXSIZE 10000
/* 栈的基本操作 */
typedef struct {
int *data;
int top;
} Stack;
bool emptyStack(Stack *S) {
return S->top == 0;
}
/* push元素 */
void pushStack(Stack *S, int x) {
if (S->top == MAXSIZE) {
return;
}
S->data[S->top++] = x;
}
/* pop元素 */
int popStack(Stack *S) {
if (emptyStack(S)) {
return -1;
}
return S->data[--S->top];
}
typedef struct {
Stack *s1;
Stack *s2;
} CQueue;
/*创建并初始化CQueue*/
CQueue* cQueueCreate() {
CQueue *obj = (CQueue*)malloc(sizeof(CQueue));
obj->s1 = (Stack*)malloc(sizeof(Stack));
obj->s1->data = (int*)malloc(sizeof(int) * MAXSIZE);
obj->s1->top = 0;
obj->s2 = (Stack*)malloc(sizeof(Stack));
obj->s2->data = (int*)malloc(sizeof(int) * MAXSIZE);
obj->s2->top = 0;
return obj;
}
/* push元素时, 只往S1中push(入队操作) */
void cQueueAppendTail(CQueue* obj, int value) {
pushStack(obj->s1, value);
}
/* 若此前未入队(即两个栈均空)则return -1,否则把已经入队的元素重新push到s2组成逆序的s1栈,然后便可以通过这个逆序栈实现出队操作 */
int cQueueDeleteHead(CQueue* obj) {
if (emptyStack(obj->s1) && emptyStack(obj->s2)) {
return -1;
}
int x;
if (emptyStack(obj->s2)) {
while (!emptyStack(obj->s1)) {
x = popStack(obj->s1);
pushStack(obj->s2, x);
}
}
return popStack(obj->s2);
}
/* 释放申请的空间 */
void cQueueFree(CQueue* obj) {
free(obj->s1->data);
free(obj->s2->data);
free(obj->s1);
free(obj->s2);
free(obj);
}
3.关于某些解答:我想大家如果有了栈和队列的基本知识把代码从头到尾看一遍,应该就对这道题十分明了了。我这里主要是总结一些我自己关于这段代码的收获,于我而言这段代码妙在整个操作通过函数实现模块化,这样减少额外的思考时间以及代码量。
如本道题是需要用两个栈实现入队和出队,其实就用入栈模拟入队,入栈后利用另一个栈实现逆序然后再出栈模拟出队。
而函数模块化便是先写出栈的基本操作,以便后续在实现队列的基本操作中能直接使用函数,如本题中入队函数cQueueAppendTail中需要pushStack函数来入栈。出队函数cQueueDeleteHead中需要emptyStack函数判空,popStack函数出栈、pushStack入栈