C++实现用两个栈模拟一个队列

  • 问题描述

用两个栈来实现一个队列,队列的声明如下,实现其中的两个函数,分别完成在队列尾部插入节点和在队列头部删除节点的操作。

声明:

template <typename T> class CQueue
{
public:
    CQueue(void);
    ~CQueue(void);

    void appendTail(const T& element)
    T deleteHead();

privite:
    stack <T> stack1;
    stack <T> stack2;    
}

其中appendTail函数是队列尾部插入节点函数,deleteHead是删除队列头部节点函数。

  • 问题分析

众所周知栈是一种先进后出的结构,而队列是先进先出的。如果我们需要使用两个FILO的结构实现FIFO,不妨这么思考:

分别给两个栈编号,叫做stack1和stack2.我们插入数据时,先将数据都按顺序给stack1里压栈。比如我传入的数据是1,2,3,按照 队列来说输出也应该是1,2,3.我们先将1,2,3压入stack1,那么此时stack1从栈底到栈顶分别为1,2,3.接着,我们将stack1全部出栈,并且每出一个就向stack2压栈。完成这步操作之后,stack2中的数据从栈底到栈顶就是3,2,1了。此时对stack2进行出栈操作,顺序就和队列的完全一样了。

那么,如果我们现在已经将stack1中的数据全部压栈进入stack2了,这时又插入了一个数据,该怎么处理呢?

我们只需将新插入的数据压入stack1,并且只要stack2非空的话,stack1就不用向stack2压栈。这样就保证了即使新插入数据,也不会对模拟队列造成影响。

对于题中要求的两个函数:首先第一个要求在队列尾插入数据。我们经过上面的分析相信你也体会到了,其实stack1就是我们模拟队列的队尾。只不过“队尾”中的节点需要出栈再压入stack2才能用于出队。所以具体实现只需要stack1.push(element)。

第二个问题:先判断stack2是否空,为空的话就从stack1中拿节点压栈。如果stack1也为空的话,队列就是真正的空队,无法进行pop操作了。否则,定义一个T类型的变量,记录stack2.top()用于返回,然后stack2调用一次pop函数即可。

具体代码:

template <typename T> void CQueue <T>::appendTail(const T& element)
{
    stack1.push(element);
}

template <typename T> T CQueue<T>::deleteHead()
{
    if(stack2.size() <= 0)
    {
        while(stack1.size() > 0)
        {
            T& data = stack1.top();
            stack1.pop();
            stack2.push(data);
        }
    }

    if(stack2.size() == 0)
    {
        throw new exception("Queue is empty.");
    }

    T head = stack2.top();
    stack2.pop();
    return head;
}

 

抱歉,我可以回答这个问题。以下是使用两个链栈模拟队列的 C 代码: ``` #include <stdio.h> #include <stdlib.h> typedef struct Node { int value; struct Node* next; } Node; typedef struct { Node* head; Node* tail; } Queue; typedef struct { Node* head; } Stack; void push(Stack* stack, int value) { Node* node = (Node*) malloc(sizeof(Node)); node->value = value; node->next = stack->head; stack->head = node; } int pop(Stack* stack) { if (!stack->head) { printf("Error: stack is empty!\n"); return -1; } int value = stack->head->value; Node* tmp = stack->head; stack->head = tmp->next; free(tmp); return value; } void enqueue(Queue* queue, int value) { push(queue->tail, value); } int dequeue(Queue* queue) { if (!queue->head->next) { printf("Error: queue is empty!\n"); return -1; } while (queue->tail->next) { push(queue->head, pop(queue->tail)); } int value = pop(queue->head); while (queue->head->next) { push(queue->tail, pop(queue->head)); } return value; } int main() { Queue* queue = (Queue*) malloc(sizeof(Queue)); queue->head = (Node*) malloc(sizeof(Node)); queue->tail = (Node*) malloc(sizeof(Node)); queue->head->next = queue->tail->next = NULL; enqueue(queue, 10); enqueue(queue, 20); enqueue(queue, 30); printf("%d\n", dequeue(queue)); printf("%d\n", dequeue(queue)); printf("%d\n", dequeue(queue)); printf("%d\n", dequeue(queue)); return 0; } ``` 此代码可以实现使用两个链栈模拟队列,并且可以操作进入队列和从队列输出。在此示例代码中,enqueue 函数将元素添加到队列中,dequeue 函数将队头的元素从队列中弹出,并返回该元素的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值