数据结构之栈与队列的面试题:用两个队列实现一个栈

首先要用队列实现栈,我们主要的问题是,应该让先入队列的元素后出去,这样就是栈的操作了,那该如何操作呢?
我们这里的思路是,首先两个队列,起初在入栈的时候插入到任意一个空队列当中即可,接下来,如果入栈应该插入到一个有元素的队列当中去。在出栈的时候,应该把有元素的队列内的前n-1个元素全部入到另一个空队列内部,接着把剩下的最后一个元素出栈即可。
这里写图片描述

//实现如下
#include <stdio.h>
#include "seqqueue.h"

typedef struct stack_by2queue{
  SeqQueue queue1;
  SeqQueue queue2;
}stack_by2queue;

void stack_by2queueInit(stack_by2queue* q)//初始化栈
{
  if(q == NULL)
  {
    return;
  }

  SeqQueueInit(&q->queue1);
  SeqQueueInit(&q->queue2);
  return;
}

void stack_by2queuePush(stack_by2queue* q, SeqQueueType value)//入栈
{
  if(q == NULL) {
    return;
  }
  if(q->queue1.size != 0) {
    SeqQueuePush(&q->queue1, value);
  } else {
    SeqQueuePush(&q->queue2, value);
  }
  return;
}

void stack_by2queuePop(stack_by2queue* q)//出栈
{
  if(q == NULL) {
    return;
  }
  if(q->queue1.size == 0 && q->queue2.size == 0) {
    return;
  }

  SeqQueueType top;

  while(1) {
    if(q->queue1.size != 0) {
      while(1)
      {
        if(q->queue1.size == 1) {
          SeqQueuePop(&q->queue1);
          return;
        }
        SeqQueueGetFront(&q->queue1, &top);
        SeqQueuePush(&q->queue2, top);
        SeqQueuePop(&q->queue1);
      }
    } else {
      while(1)
      {
        if(q->queue2.size == 1) {
          SeqQueuePop(&q->queue2);
          return;
        }
        SeqQueueGetFront(&q->queue2, &top);
        SeqQueuePush(&q->queue1, top);
        SeqQueuePop(&q->queue2);
      }
    }
  }
}

int stack_by2queueTop(stack_by2queue* q, SeqQueueType* value)//取栈顶元素
{
  if(q == NULL) {
    return -1;
  }
  if(q->queue1.size == 0 && q->queue2.size == 0) {
    return -1;
  }

  while(1) {
    if(q->queue1.size != 0) {
      while(1)
      {
        SeqQueueGetFront(&q->queue1, value);
        SeqQueuePush(&q->queue2, *value);
        SeqQueuePop(&q->queue1);
        if(q->queue1.size == 0) {
          return 1;
        }
      }
    } else {
      while(1)
      {
        SeqQueueGetFront(&q->queue2, value);
        SeqQueuePush(&q->queue1, *value);
        SeqQueuePop(&q->queue2);
        if(q->queue2.size == 0) {
          return 1;
        }
      }
    }
  }
}

void stack_by2queuePrint(stack_by2queue* q)
{
  if(q == NULL) {
    return;
  }

  size_t i = 0;

  if(q->queue1.size != 0) {
    for(i = q->queue1.head; i != q->queue1.tail; ++i) {
      if(i >= SQUEUEMAX) {
        i = 0;
      }
      printf("%c ",q->queue1.data[i]);
    }
  } else {
    for(i = q->queue2.head; i != q->queue2.tail; ++i) {
      if(i >= SQUEUEMAX) {
        i = 0;
      }
      printf("%c ",q->queue2.data[i]);
    }
  }
  printf("\n");

  return;
}

这里我们利用之前所实现的队列的基本操作来帮助我们完成一些操作。

//测试代码如下
int main()
{
  stack_by2queue q;
  SeqQueueType value;
  int ret;
  stack_by2queueInit(&q);
  stack_by2queuePush(&q, 'a');
  stack_by2queuePush(&q, 'b');
  stack_by2queuePush(&q, 'c');
  stack_by2queuePush(&q, 'd');
  stack_by2queuePrint(&q);
  ret = stack_by2queueTop(&q, &value);
  printf("expected ret 1, actual ret %d\n",ret);
  printf("expected value d, actual value %c\n",value);

  stack_by2queuePop(&q);
  stack_by2queuePrint(&q);
  ret = stack_by2queueTop(&q, &value);
  ret = stack_by2queueTop(&q, &value);
  printf("expected ret 1, actual ret %d\n",ret);
  printf("expected value c, actual value %c\n",value);

  stack_by2queuePop(&q);
  stack_by2queuePrint(&q);
  ret = stack_by2queueTop(&q, &value);
  ret = stack_by2queueTop(&q, &value);
  printf("expected ret 1, actual ret %d\n",ret);
  printf("expected value b, actual value %c\n",value);

  stack_by2queuePop(&q);
  stack_by2queuePrint(&q);
  ret = stack_by2queueTop(&q, &value);
  ret = stack_by2queueTop(&q, &value);
  printf("expected ret 1, actual ret %d\n",ret);
  printf("expected value a, actual value %c\n",value);

  stack_by2queuePop(&q);
  stack_by2queuePrint(&q);
  ret = stack_by2queueTop(&q, &value);
  ret = stack_by2queueTop(&q, &value);
  printf("expected ret -1, actual ret %d\n",ret);

  return 0;
}

欢迎大家共同讨论,如有错误及时联系作者指出,并改正。谢谢大家!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值