循环队列、队列实现栈

在对队列的学习时认识到了两种应用队列的场景,一是循环队列,另一个是用队列来实现栈。

  1. 循环队列:因为在对队列进行删除操作时会造成空间的浪费,所以引入了循环队列的思想。
    循环队列中,有一个头front、一个尾rear还有一个计数器count,起始时front和rear在同一位置,count等于0。进行插入时,rear向后移动,count++;删除时front向后移动,count–。count可以用来判定队列是否满和空。
    值得注意的是:在循环队列中,有效长度为***(rear - front + N) % N***
    以下一道循环队列的设计题
//创建的循环队列的结构体类型变量
typedef struct {
    int capacity;
    int *array;
    int front;
    int rear;
    int count;
} MyCircularQueue;

MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue *mq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));//在栈上创建一个指针,指向申请的变量
    mq->array = (int*)malloc(sizeof(int)*k);
    mq->front = mq->rear = mq->count = 0;
    mq->capacity = k;
    return mq;
}
//获取队尾元素
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
    if(obj->count == obj->capacity){
        return false;
    }
    obj->array[obj->rear++] = value;
    if(obj->rear == obj->capacity){
        obj->rear = 0;
    }
    obj->count++;
    return true;
}
//删除元素
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
  if(obj->count == 0){
      return false;
  }
  obj->front++;
  if(obj->front == obj->capacity){
      obj->front = 0;
  }
  obj->count--;
  return true;
}
//获取队头元素
int myCircularQueueFront(MyCircularQueue* obj) {
  if(obj->count == 0){
      return -1;
  }
  return obj->array[obj->front];
}
//获取队尾元素
int myCircularQueueRear(MyCircularQueue* obj) {
  if(obj->count == 0){
      return -1;
  }
  return obj->array[(obj->rear-1 + obj->capacity) % obj->capacity];
}
//判断队列是否为空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
  if(obj->count){
      return false;
  }
  return true;
}
//判断队列是否为满
bool myCircularQueueIsFull(MyCircularQueue* obj) {
  if(obj->count == obj->capacity){
      return true;
  }
  return false;
}
//销毁队列
void myCircularQueueFree(MyCircularQueue* obj) {
    free(obj->array);
    obj->front = obj->rear = obj->count = 0;
}

  1. 用队列实现栈。
    栈的结构是先进后出,队列是先进先出。在使用队列模拟实现栈时,我们要用到两个队列q1,q2。
    在进行入栈操作时,我们看哪个队列不为空就把元素插入哪个队列。
    出栈时,哪个队列不为空,当它的元素大于一,就把它里边的元素出队放到另一个队列中,最后再将剩下一个元素的队列中的元素出队,这时就实现了出栈操作。
    获取栈顶元素其实就是判断当前哪个队列不为空,就获取哪个队列的队尾元素,栈顶相当于队尾。
    以下基于队列基础上实现的栈:

typedef struct {
    Queue q1;
    Queue q2;
} MyStack;

MyStack* myStackCreate() {
    MyStack *ms = (MyStack*)malloc(sizeof(MyStack));
    QueueInit(&ms->q1);
    QueueInit(&ms->q2);
    return ms;
}
//入栈
void myStackPush(MyStack* obj, int x) {
    if(obj == NULL){
        return;
    }
    //哪个队列不为空,就把元素插入哪个队列中
    if(!QueueEmpty(&obj->q1)){
        QueuePush(&obj->q1,x);
    }
    else{
        QueuePush(&obj->q2,x);
    }
}
//出栈
int myStackPop(MyStack* obj) {
    int ret = 0;
    if(!QueueEmpty(&obj->q1)){
        while(QueueSize(&obj->q1)>1){
            //将q1中的元素插入q2中
            QueuePush(&obj->q2,QueueFront(&obj->q1));
            QueuePop(&obj->q1);
        }
        ret = QueueFront(&obj->q1);
        QueuePop(&obj->q1);
    }
    else{
        while(QueueSize(&obj->q2)>1){
            QueuePush(&obj->q1,QueueFront(&obj->q2));
            QueuePop(&obj->q2);
        }
        ret = QueueFront(&obj->q2);
        QueuePop(&obj->q2);
    }
    return ret;
}
//获取栈顶元素
int myStackTop(MyStack* obj) {
    if(obj == NULL){
        return;
    }
    if(!QueueEmpty(&obj->q1)){
        return QueueBack(&obj->q1);
    }
    else{
        return QueueBack(&obj->q2);
    }
}
//判断栈是否为空
bool myStackEmpty(MyStack* obj) {
    if(QueueEmpty(&obj->q1)&&QueueEmpty(&obj->q2)){
        return true;
    }
    else{
        return false;
    }
}

void myStackFree(MyStack* obj) {
    QueueDestroy(&obj->q1);
    QueueDestroy(&obj->q2);
    free(obj);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值