设置循环队列

 链接:力扣

//1.用数组模拟实现循环队列,用int head;和int tail记录头和尾的位置,使得头删不用挪动数组,只需要挪动int head;
//2.或者用链表实现,头删也不用挪动数组

typedef struct {
    int* a;//动态数组
    int k;//元素个数
    int head;//
    int tail;
} MyCircularQueue;




//初始化循环队列
MyCircularQueue* myCircularQueueCreate(int k) {
    MyCircularQueue* obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));
    assert(obj);
    obj->a=(int *)malloc(sizeof(int)*(k+1));//法1.因为tail==head只能判空,不能判满,所以要多开一个空间使tail->next=head;判满。法2.其实也可以根据tail==head和k的数值判满。这里用的是法1。
    assert(obj->a);
    obj->head=obj->tail=0;
    obj->k=k;//数组k+1长,有k个元素
    return obj;
}

//判空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
    assert(obj);
     return obj->head==obj->tail;
}



//判满
bool myCircularQueueIsFull(MyCircularQueue* obj) {
    assert(obj);
          int next=obj->tail +1;
     //!!!注意next==k+1时候也要使其变为0;
     //法1. next%=(k+1);
     //法2. 
     if(next==obj->k +1)
     {
         next=0;
     }
     return next==obj->head;
     
}


//从队尾入队
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) //入队
{
    assert(obj);
    //判满--满了则返回false
    if( myCircularQueueIsFull(obj))
    return false;

    //一开始有元素和无元素是一样的,head指向首元素,tail指向尾元素的下一个
       obj->a[obj->tail]=value;
       obj->tail++;
    
      //法1. obj->tail%=(k+1);--因为数组k+1长,放k个元素
      //法2.
      if(obj->tail==obj->k+1)
      {
          obj->tail=0;
      }
       return true;
}


//从队头出队列
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
    assert(obj);
    if(myCircularQueueIsEmpty(obj))
    return false;

    obj->head++;

    //法1. head%=(k+1);
    //法2. 
    if(obj->head==obj->k+1)
    {
        obj->head=0;
    }
    return true;
}


//取队头元素
int myCircularQueueFront(MyCircularQueue* obj) {
    assert(obj);
    if(myCircularQueueIsEmpty(obj))
    return -1;

    return obj->a[obj->head];
}



//取队尾元素
int myCircularQueueRear(MyCircularQueue* obj) {
    assert(obj);
    if(myCircularQueueIsEmpty(obj))
    return -1;
    //这里不能用取模手段了,因为tail-1==-1;
    //把tail-1再怎么模,-1%(k+1)得(-1);
    int prev=obj->tail-1;
    if(prev==-1)
    {
        prev=obj->k;
        //或,prev+=obj->k +1
    }
    return obj->a[prev];
}


//释放
void myCircularQueueFree(MyCircularQueue* obj) { 
    free(obj->a);
    free(obj);
}

/**
 * Your MyCircularQueue struct will be instantiated and called as such:
 * MyCircularQueue* obj = myCircularQueueCreate(k);
 * bool param_1 = myCircularQueueEnQueue(obj, value);
 
 * bool param_2 = myCircularQueueDeQueue(obj);
 
 * int param_3 = myCircularQueueFront(obj);
 
 * int param_4 = myCircularQueueRear(obj);
 
 * bool param_5 = myCircularQueueIsEmpty(obj);
 
 * bool param_6 = myCircularQueueIsFull(obj);
 
 * myCircularQueueFree(obj);
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值