题目:如下图
答案:如下图
//使用数组的方式进行求解
typedef struct {
int* _a;
int _front;
int _rear;
int _k;
} MyCircularQueue;
//开辟数组空间多开一个并且指针也开辟空间
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* q = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
q->_a= (int*)malloc(sizeof(int) * (k + 1));
q->_k = k;
q->_front = 0;
q->_rear = 0;
return q;
}
//用到相应函数进行提前声明
bool myCircularQueueIsEmpty(MyCircularQueue* obj)
bool myCircularQueueIsFull(MyCircularQueue* obj)
//向循环队列插入一个元素。如果成功插入则返回真。
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if (myCircularQueueIsFull(obj))
{
return false;
}
obj->_a[obj->_rear] = value;
++obj->_rear;
obj->_rear%=(obj->_k + 1);
return true;
}
//从循环队列中删除一个元素。如果成功删除则返回真
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
{
return false;
}
++obj->_front;
obj->_front %= (obj->_k + 1);//仅仅是做了,但是没有去赋值
return true;
}
//从队首获取元素。如果队列为空,返回-1
int myCircularQueueFront(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
{
return -1;
}
else
{
return obj->_a[obj->_front];
}
}
//从获取队尾元素。如果队列为空,返回-1
int myCircularQueueRear(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
return -1;
else
if (obj->_rear == 0)
return(obj->_a[obj->_k]);
return obj->_a[obj->_rear-1];
}
//为空返回1,不为空返回0
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->_front ==obj->_rear
}
//为满返回1,不为满返回0
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->_rear+1)%(obj->_k +1) == obj->_front;
}
//释放
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->_a);
free(obj);
}
解析:
(1)使用数组的方式进行求解
typedef struct {
int* _a;
int _front;
int _rear;
int _k;
} MyCircularQueue;
数组便于判断循环队列中的空与满
开辟空间时多开辟一个空间用于判断空满,当_front==_rear时循环队列为空,由于留了一个结点用于判断满,故当且仅空一个结点时为满,,即_front==_rear+1时循环队列为满,,,当_rear为最后一个结点时采用 (_rear+1)%(k+1)来使其为0 此时0=0 故采用 _front==(_rear+1)%(k+1)来判断循环队列为满
(2)多开辟一个数组空间并且开辟结构体空间
MyCircularQueue* myCircularQueueCreate(int k) {
MyCircularQueue* q = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
q->_a= (int*)malloc(sizeof(int) * (k + 1));
q->_k = k;
q->_front = 0;
q->_rear = 0;
return q;
}
(3)用到相应函数进行提前声明
bool myCircularQueueIsEmpty(MyCircularQueue* obj);
bool myCircularQueueIsFull(MyCircularQueue* obj) ;
(4)向循环队列插入一个元素。如果成功插入则返回真
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
if (myCircularQueueIsFull(obj))
{
return false;
}
obj->_a[obj->_rear] = value;
++obj->_rear;
obj->_rear%=(obj->_k + 1);
return true;
}
(5)使用判断是否满的函数进行判断如果满的话就不能插入,返回false
当_rear的值加一后可能超过_k的值出现数组越界,这时候就采取obj->_rear%=(obj->_k + 1)的操作使其成为0;
执行完之后返回true
(6)从循环队列中删除一个元素。如果成功删除则返回真
bool myCircularQueueDeQueue(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
{
return false;
}
++obj->_front;
obj->_front %= (obj->_k + 1);
return true;
}
先用判断是否为空的函数进行判断,若为空则无法进行删除,返回false
直接将++obj->_front即可完成删除操作,其本质为下标加一,访问首元素时是用下标进行访问,下标加一访问的是下一个元素,值得注意的是front加一后有可能出现数组越界,图解和(5)中类似这里就不再列举了
(7)从队首获取元素。如果队列为空,返回-1
int myCircularQueueFront(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
{
return -1;
}
else
{
return obj->_a[obj->_front];
}
}
当数组为空的时候无法在队首获取元素,使用判断是否为空的函数进行判断,若为空则返回-1
不为空则return obj->_a[obj->_front]
(8)从获取队尾元素。如果队列为空,返回-1
int myCircularQueueRear(MyCircularQueue* obj) {
if (myCircularQueueIsEmpty(obj))
return -1;
else
if (obj->_rear == 0)
return(obj->_a[obj->_k]);
return obj->_a[obj->_rear-1];
}
当数组为空的时候无法在队尾获取元素,使用判断是否为空的函数进行判断,若为空则返回-1
不为空则return obj->_a[obj->_rear-1]
特别的当_rear在0的时候obj->_rear-1等于-1,用obj->_a[obj->_rear-1]进行访问则包出现数组越界,这时候用if语句判断,返回return(obj->_a[obj->_k]);即可
(9)判断是否为空,为空返回1,不为空返回0
bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
return obj->_front ==obj->_rear
}
判断是否为满,为满返回1,不为满返回0
bool myCircularQueueIsFull(MyCircularQueue* obj) {
return (obj->_rear+1)%(obj->_k +1) == obj->_front;
}
开辟空间时多开辟一个空间用于判断空满,当_front==_rear时循环队列为空,由于留了一个结点用于判断满,故当且仅空一个结点时为满,,即_front==_rear+1时循环队列为满,,,当_rear为最后一个结点时采用 (_rear+1)%(k+1)来使其为0 此时0=0 故采用 _front==(_rear+1)%(k+1)来判断循环队列为满
(10)释放循环队列
void myCircularQueueFree(MyCircularQueue* obj) {
free(obj->_a);
free(obj);
}
使用free()函数释放数组以及obj结构体
到这里我们解题完毕
如果对您有帮助的话点一个免费的赞和收藏叭!
由于作者水平不足,如果有任何错误,麻烦读者评论在评论区指点一下,谢谢!