评论

收藏

[C++] #yyds干货盘点#算法开启循环队列武魂

编程语言 编程语言 发布于:2021-12-28 23:11 | 阅读数:408 | 评论:0

设计循环队列

题目
DSC0000.png

我们会使用一种队列叫循环队列。如操作系统课程讲解生产者消费者模型时可以就会使用循环队列。==环形队列可以使用数组实现,也可以使用循环链表实现。==
DSC0001.png

DSC0002.png

==可以认为队尾tail不是队尾,而是我们认知上队尾的后一个==

数组形式(通过下标控制来达到循环的效果)
DSC0003.gif

环队结构体(数组)
typedef struct {
  int* a;
  int front;
  int tail;
  int k;//数组元素(队列长度)
} MyCircularQueue;
环队初始化
MyCircularQueue* myCircularQueueCreate(int k) {
  MyCircularQueue* q = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
  q->a = (int*)malloc(sizeof(int)*(k+1));//队列长度为k我们要多开一个
  q->front = q->tail = 0;
  q->k = k;
  return q;
}
判断环队为空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
  return obj->front == obj->tail;
}
判断环队为满
bool myCircularQueueIsFull(MyCircularQueue* obj) {
  return (obj->tail+1)%(obj->k+1) == obj->front;
}
环队入数据并入成功返回真
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
  if(!myCircularQueueIsFull(obj))
  {
    obj->a[obj->tail] = value;//不是队满就下标tail的数据为value
    obj->tail++;
    obj->tail %= obj->k+1;//tail就步进一位
    return true;
  }
  return false;//队满就插不进去了
}
环队删数据并删成功返回真
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
  if(!myCircularQueueIsEmpty(obj))
  {
    obj->front++;//队不空就是出队,头标步进就行了
    obj->front %= obj->k+1;
    return true;
  }
  return false;//对空就删不了了
}
环队取队头数据(对空返回-1)
int myCircularQueueFront(MyCircularQueue* obj) {
  if(!myCircularQueueIsEmpty(obj))
  {
    return obj->a[obj->front]; //取front位置的数据就行     
  }
  return -1;
}
环队取队尾数据(对空返回-1)
int myCircularQueueRear(MyCircularQueue* obj) {
  if(!myCircularQueueIsEmpty(obj))
  {    
    return obj->a[obj->tail == 0 ? obj->k : obj->tail-1];//取tail前一个数据就行,tail为0,前一个就是k位置数据    
  }
  return -1;
}
环队销毁
void myCircularQueueFree(MyCircularQueue* obj) {
  free(obj->a);
  obj->a = NULL;
  obj->front = 0;
  obj->tail = 0;
  obj->k = 0;
  free(obj);
}
DSC0004.png

DSC0005.png

环队(数组实现)
typedef struct {
  int* a;
  int front;
  int tail;
  int k;//数组元素(队列长度)
} MyCircularQueue;
MyCircularQueue* myCircularQueueCreate(int k) {
  MyCircularQueue* q = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
  q->a = (int*)malloc(sizeof(int)*(k+1));//队列长度为k我们要多开一个
  q->front = q->tail = 0;
  q->k = k;
  return q;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
  if(!myCircularQueueIsFull(obj))
  {
    obj->a[obj->tail] = value;//不是队满就下标tail的数据为value
    obj->tail++;
    obj->tail %= obj->k+1;//tail就步进一位
    return true;
  }
  return false;//队满就插不进去了
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
  if(!myCircularQueueIsEmpty(obj))
  {
    obj->front++;//队不空就是出队,头标步进就行了
    obj->front %= obj->k+1;
    return true;
  }
  return false;//对空就删不了了
}
int myCircularQueueFront(MyCircularQueue* obj) {
  if(!myCircularQueueIsEmpty(obj))
  {
    return obj->a[obj->front]; //取front位置的数据就行     
  }
  return -1;
}
int myCircularQueueRear(MyCircularQueue* obj) {
  if(!myCircularQueueIsEmpty(obj))
  {    
    return obj->a[obj->tail == 0 ? obj->k : obj->tail-1];//取tail前一个数据就行,tail为0,前一个就是k位置数据    
  }
  return -1;
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
  return obj->front == obj->tail;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
  return (obj->tail+1)%(obj->k+1) == obj->front;
}
void myCircularQueueFree(MyCircularQueue* obj) {
  free(obj->a);
  obj->a = NULL;
  obj->front = 0;
  obj->tail = 0;
  obj->k = 0;
  free(obj);
}
链表形式
DSC0006.gif

环队结构体(链表)
typedef int CQDataType;//环队数据类型
typedef struct CQNode
{
  CQDataType x;//环队节点数据
  struct CQNode* next;//环队节点指针
}CQNode;
typedef struct {
  CQNode* head;
  CQNode* tail;
  int k;
} MyCircularQueue;//空环队就两个裸指针
环队初始化
MyCircularQueue* myCircularQueueCreate(int k) {
  MyCircularQueue* cq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
  CQNode* cur = (CQNode*)malloc(sizeof(CQNode));
  cq->k = k;
  cq->head = cq->tail = cur;
  while(k--)
  {
    CQNode* newnode = (CQNode*)malloc(sizeof(CQNode));
    CQNode* tail = cq->tail;//最后一个节点
    tail->next = newnode;//最后一个节点指向新的节点
    newnode->next = cq->head;//新的节点指向头节点
    cq->tail=newnode;
  }
  cq->head = cq->tail;
  return cq;
}
判断环队为空
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
  assert(obj->head && obj->tail);
  return obj->head == obj->tail;
}
判断环队为满
bool myCircularQueueIsFull(MyCircularQueue* obj) {
  assert(obj->head && obj->tail);
  return obj->tail->next == obj->head;
}
环队入数据并入成功返回真
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
  assert(obj->head && obj->tail);
  if(!myCircularQueueIsFull(obj))
  {
    obj->tail->x = value;
    obj->tail = obj->tail->next;
    return true;
  }
  return false;
}
环队删数据并删成功返回真
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
  assert(obj->head && obj->tail);
  if(!myCircularQueueIsEmpty(obj))
  {
    obj->head = obj->head->next;
    return true;
  }
  return false;
}
环队取队头数据(对空返回-1)
int myCircularQueueFront(MyCircularQueue* obj) {
  assert(obj->head && obj->tail);
  if(!myCircularQueueIsEmpty(obj))
    return obj->head->x;
  return -1;
}
环队取队尾数据(对空返回-1)
int myCircularQueueRear(MyCircularQueue* obj) {
  assert(obj->head && obj->tail);
  if(!myCircularQueueIsEmpty(obj))
  {
    CQNode*ret=obj->head;
    while(ret->next!=obj->tail)
    {
      ret=ret->next;
    }
    return ret->x;
  }
  return -1;  
}
环队销毁
void myCircularQueueFree(MyCircularQueue* obj) {
  assert(obj->head && obj->tail);
  while(obj->head!=obj->tail)
  {
    CQNode*ret=obj->tail;
    obj->tail=obj->tail->next;
    free(ret);
  }
  free(obj->head);
  free(obj);
}
DSC0007.png

环队(链表实现)
typedef int CQDataType;//环队数据类型
typedef struct CQNode
{
  CQDataType x;//环队节点数据
  struct CQNode* next;//环队节点指针
}CQNode;
typedef struct {
  CQNode* head;
  CQNode* tail;
  int k;
} MyCircularQueue;//空环队就两个裸指针
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj);
MyCircularQueue* myCircularQueueCreate(int k) {
  MyCircularQueue* cq = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
  CQNode* cur = (CQNode*)malloc(sizeof(CQNode));
  cq->k = k;
  cq->head = cq->tail = cur;
  while(k--)
  {
    CQNode* newnode = (CQNode*)malloc(sizeof(CQNode));
    CQNode* tail = cq->tail;//最后一个节点
    tail->next = newnode;//最后一个节点指向新的节点
    newnode->next = cq->head;//新的节点指向头节点
    cq->tail=newnode;
  }
  cq->head = cq->tail;
  return cq;
}
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
  assert(obj->head && obj->tail);
  if(!myCircularQueueIsFull(obj))
  {
    obj->tail->x = value;
    obj->tail = obj->tail->next;
    return true;
  }
  return false;
}
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
  assert(obj->head && obj->tail);
  if(!myCircularQueueIsEmpty(obj))
  {
    obj->head = obj->head->next;
    return true;
  }
  return false;
}
int myCircularQueueFront(MyCircularQueue* obj) {
  assert(obj->head && obj->tail);
  if(!myCircularQueueIsEmpty(obj))
    return obj->head->x;
  return -1;
}
/*int myCircularQueueRear(MyCircularQueue* obj) {
  assert(obj->head && obj->tail);
  if(!myCircularQueueIsEmpty(obj))
  {
    CQNode* ret = obj->head;//这个ret 是用来找tail前一个的,不可用直接返回tail,会改变原来环队的链接关系
    while(--obj->k)
    {
       obj->tail = obj->tail->next;
    }    
    ret = obj->tail;
    obj->tail = obj->tail->next;
    return obj->tail->x;
  }
  return -1;  
}*/
int myCircularQueueRear(MyCircularQueue* obj) {
  assert(obj->head && obj->tail);
  if(!myCircularQueueIsEmpty(obj))
  {
    CQNode*ret=obj->head;
    while(ret->next!=obj->tail)
    {
      ret=ret->next;
    }
    return ret->x;
  }
  return -1;  
}
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
  assert(obj->head && obj->tail);
  return obj->head == obj->tail;
}
bool myCircularQueueIsFull(MyCircularQueue* obj) {
  assert(obj->head && obj->tail);
  return obj->tail->next == obj->head;
}
void myCircularQueueFree(MyCircularQueue* obj) {
  assert(obj->head && obj->tail);
  while(obj->head!=obj->tail)
  {
    CQNode*ret=obj->tail;
    obj->tail=obj->tail->next;
    free(ret);
  }
  free(obj->head);
  free(obj);
}
实际上这题我报错我不想找了太恶心了(家凌帮我找错的非常感谢)
DSC0008.jpg



关注下面的标签,发现更多相似文章