使用2个队列实现堆栈

时间:2015-01-14 04:30:45

标签: c++ c stack queue

为什么此代码有效:

#include <cstdio>
#include <cstdlib>

#define N n *
#define Q q *
#define S s *

typedef struct n
{
    int data;
    struct N nxt;
}n;

typedef struct q
{
    N f;
    N r;
}q;

typedef struct stack
{
    Q q1;
    Q q2;
}s;
Q Createq()
{
    Q qq = (Q)malloc(sizeof(q));
    qq->f = qq->r  = 0;
    return qq;
}

S CreateStk()
{
    S stk = (S)malloc(sizeof(s));
    stk->q1 = Createq();
    stk->q2 = Createq();
    return stk;
}

int Deq(Q qq)
{
    if(qq->f == 0 && qq->r == 0) return -1;
    N nn = qq->r;
    int data = nn->data;
    qq->r = qq->r->nxt;
    free(nn);
    if(!qq->r)
        qq->f = 0;
    return data;
}

void Enq(Q qq, int data)
{
    if(!qq->f)
    {
        N nn = (N)malloc(sizeof(n));
        nn->data = data;
        nn->nxt = 0;
        qq->f = qq->r = nn;
    }
    else
    {
        N nn = (N)malloc(sizeof(n));
        nn->data = data;
        nn->nxt = 0;
        qq->f->nxt = nn;
        qq->f = nn;
    }
}

void Push(S stk, int data)
{
    Enq(stk->q2,data);

    while(stk->q1->f)
    {
        Enq(stk->q2,Deq(stk->q1));
    }

    Q t = stk->q1;
    stk->q1 = stk->q2;
    stk->q2 = t;
}

int Pop(S stk)
{
    return Deq(stk->q1);
}
int main() 
{
    S stk = CreateStk();
    Push(stk,10);
    Push(stk,30);
    Push(stk,40);
    Push(stk,50);
    printf("\nPopped: %d.", Pop(stk));
    printf("\nPopped: %d.", Pop(stk));
    printf("\nPopped: %d.", Pop(stk));
    printf("\nPopped: %d.", Pop(stk));
    return 0;
    return 0;
}

输出:

Popped: 50.
Popped: 40.
Popped: 30.
Popped: 10.

虽然这不是:

#include <cstdio>
#include <cstdlib>

#define N n *
#define Q q *

typedef struct n
{
    int data;
    struct N nxt;
}n;

typedef struct q
{
    N f;
    N r;
}q;

Q Createq()
{
    Q qq = (Q)malloc(sizeof(q));
    qq->f = qq->r  = 0;
    return qq;
}

int Deq(Q qq)
{
    if(qq->f == 0 && qq->r == 0) return -1;
    N nn = qq->r;
    int data = nn->data;
    qq->r = qq->r->nxt;
    free(nn);
    if(!qq->r)
        qq->f = 0;
    return data;
}

void Enq(Q qq, int data)
{
    if(!qq->f)
    {
        N nn = (N)malloc(sizeof(n));
        nn->data = data;
        nn->nxt = 0;
        qq->f = qq->r = nn;
    }
    else
    {
        N nn = (N)malloc(sizeof(n));
        nn->data = data;
        nn->nxt = 0;
        qq->f->nxt = nn;
        qq->f = nn;
    }
}

void Push(Q qq1, Q qq2, int data)
{
    Enq(qq2,data);

    while(qq1->f)
    {
        Enq(qq2,Deq(qq1));
    }

    Q t = qq1;
    qq1 = qq2;
    qq2 = t;
}

int Pop(Q qq1)
{
    return Deq(qq1);
}

int main() {
    // your code goes here
    Q qq1 = Createq();
    Q qq2 = Createq();
    Push(qq1,qq2,10);
    Push(qq1,qq2,30);
    Push(qq1,qq2,40);
    Push(qq1,qq2,50);
    printf("\nPopped: %d.", Pop(qq1));
    printf("\nPopped: %d.", Pop(qq1));
    printf("\nPopped: %d.", Pop(qq1));
    printf("\nPopped: %d.", Pop(qq1));
    return 0;
}

输出:

  

弹出:-1。      弹出:-1。      弹出:-1。      弹出:-1。

预期的输出是第一个显而易见的问题标题。但是,当我在第二个例子中没有在结构中封装2个队列时,我不明白为什么代码不起作用的血腥细节。

PS:我认为问题在于Push方法 - 但不确定出了什么问题。

1 个答案:

答案 0 :(得分:3)

除了非常难以阅读之外,问题在于您的第二个Push函数会在以下代码行中更改其参数的值。

Q t = qq1;
qq1 = qq2;
qq2 = t;

qq1qq2是函数的参数,因此新值不会在调用函数(main)中更新。

解决此问题的一种方法是通过引用传递参数:

void Push(Q &qq1, Q &qq2, int data)

这样,对qq1qq2的更改也会更改调用函数中的值。