设计循环队列
题目
我们会使用一种队列叫循环队列。如操作系统课程讲解生产者消费者模型时可以就会使用循环队列。==环形队列可以使用数组实现,也可以使用循环链表实现。==
==可以认为队尾tail不是队尾,而是我们认知上队尾的后一个==
数组形式(通过下标控制来达到循环的效果)
环队结构体(数组)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);
}
环队(数组实现)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);
} 链表形式
环队结构体(链表)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);
}
环队(链表实现)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);
} 实际上这题我报错我不想找了太恶心了(家凌帮我找错的非常感谢)
|