在一个函数的接口里面,如果说它的返回值是一个地址的话,那么往往来讲,你这函数里面的内存空间的开辟必须是要向堆区去申请的malloc之流
栈的结构是先进后出,队列的结构是先进先出
无论是在main函数内部还是外部,编译器的话,它只会向上找,它不可能向下找,因为它要提高它的编译速率
字符与整数之间可以灵活转化,因为字符其实本质上就是ACSII码,就是整型。
循环队列也是队列的一种,他也要求是先进先出。
循环队列就是说队列当中整个数据的总数是确定的,然后在这个结构当中可以转圈圈,但是他毕竟也是队列的一种,因此他也是符合队列的特性,也就是说是先进先出。只不过他的空间可以重复利用,你就可以把它想象成转圈圈。它的head与front都可以在圈圈当中不断的转动,它的主要好处就在于空间可以重复利用
对于现在这个循环队列而言,就是说在最开始所有空间都应该被开辟出来,无论你是用数组模拟还是用链表去模拟,当然要开多少空间(实际上就取决于你最多能存多少个数据)这个的话一开始会告诉你的
在设计循环队列的时候,我们用的是数组去模拟循环队列,但是对于这个数组的话,需要进行一个额外的处理,因为当这个循环队列为空,你会发现两个指针是指向一起的,然后当这个循环队列满的时候,你又会发现两个指针是指向一起的,这时候为了以示区分的话,有两种方法:第一种方法的话就是说在结构体里面加一个结构体成员size去维护一下;第二种方式的话就是在数组的基础之上,额外开一个元素的空间,这个空间里面不存放任何数据,是专门用来区分上面讲的两种情况。
然后对于两个结构体成员front和rear的话,在数组里面是不能够越界的,所以说如果说走到头的话,需要从起点开始再走,这之后的话,你只需要给他取余上数组的长度就可以了。
在这边还是得强调一下,就是说这个front和rear这两个的话都是数组的下标,也是结构体的成员,在最初始状态的话,两个东西都是0。然后当有数据插入的时候,我改变的是rear,必须要弄清楚的是:rear是末尾数据的下一个元素的下标;然后等有数据需要从队头弹出的时候,我改变的是front,也就是说把front向后移一位。
然后再额外的强调一下什么时候这个循环队列是空?当rear与front一样的时候,什么时候这个循环队列是满的(因为在之前也提到过这个循环队列当中能存多少个数据k这事先已经告诉你的,是限定死的),当rear+1为front(现在不考虑取余),这时候说明这个循环队列是满的。
622. 设计循环队列 - 力扣(LeetCode)
typedef int MyQDataType;
typedef struct
{int front;int rear;int k;MyQDataType* pp;
} MyCircularQueue;MyCircularQueue* myCircularQueueCreate(int k)
{MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));if (obj==NULL){perror("malloc fail");return NULL;}obj->pp = (MyQDataType*)malloc(sizeof(MyQDataType)*(k+1));if (obj->pp==NULL){perror("malloc fail");return NULL;}obj->front=0;obj->rear=0;obj->k=k;return obj;
}bool myCircularQueueIsFull(MyCircularQueue* obj)
{assert(obj);int num=(obj->rear+1)%(obj->k+1);return num==obj->front;
}bool myCircularQueueIsEmpty(MyCircularQueue* obj)
{assert(obj);return obj->front==obj->rear;
}bool myCircularQueueEnQueue(MyCircularQueue* obj, int value)
{assert(obj);if (myCircularQueueIsFull(obj)){return false;}obj->pp[obj->rear]=value;int num=(obj->rear+1)%(obj->k+1);obj->rear=num;return true;
}bool myCircularQueueDeQueue(MyCircularQueue* obj)
{assert(obj);if (myCircularQueueIsEmpty(obj)){return false;}int num=(obj->front+1)%(obj->k+1);obj->front=num;return true;
}int myCircularQueueFront(MyCircularQueue* obj)
{assert(obj);if (myCircularQueueIsEmpty(obj)){return -1;}return obj->pp[obj->front];
}int myCircularQueueRear(MyCircularQueue* obj)
{assert(obj);if (myCircularQueueIsEmpty(obj)){return -1;}return obj->pp[(obj->rear-1+obj->k+1)%(obj->k+1)];
}void myCircularQueueFree(MyCircularQueue* obj)
{assert(obj);free(obj->pp);obj->pp=NULL;obj->front=0;obj->rear=0;free(obj);
}