循环队列的简单知识

【循环队列的简单知识】队列其实也是链表,这里讲的是顺序表示。队列,顾名思义,就是排队的队形。按照专业一点就是FIFO(first in first out) 原则,从对列头出列,从对尾入列。
因为循环队列最利用效率,也稍微增加了难度,所以要记住循环队列的表示方法。
其实很多数据结构都有很多种写法,重要是理解其思想,代码完成只是让自己更加透彻的掌握,每一种实现方式都是按其思想一步一步完成的。
先贴出结构体:

typedef struct queue {
int*Base; //数组头指针
int front; //对头
int rear; //队尾。。实际就是数组下标
int size; //队列长度
}Queue;
如果不同的数据类型 int *Base 的类型记得换,还有好多地方 ,记得就行了。
之所以用循环队列,是因为对头只能出,对尾只能入,这样就变成了上面的位置空出后就一直空着了,造成了很大的浪费啊。

我之前学的时候循环队列的时候就觉得很晕,主要是当时我的确太渣了,现在理解了其中的道理,感觉还是挺好玩的。循环的意思并没有违背对头对尾的概念,就像我在一个圆圈上开了俩个洞,一个标为头,一个标为尾,所以不管转或不转,我的标志就在那儿。
我们这样想,假如这个循环的圈圈,有6个位置,但是我们只装5个数(代码有注释),
e→ d →c →b→ a头
↑|
————————
下标是 4 3 2 1 0等到装满的时候便不能装了,然后出对是不,那么这时候a下标为0从头出去了,那么对头就变成 q->front = (q->front+1) % q->size;
成为了1,然后有数f来入队,那么此时对尾变成了 q->rear = (q->rear +1)% q->size;
成为了0,看到了没,就因为简单的取余的操作,我的下标永远在0-4间循环,就成为了循环队列。 好了,也许和我当初学的时候想的不一样,以后还是觉得把刚学的知识,马上写出感受才好,新鲜又贴近最真实的感觉。

#include #include #include typedef struct queue { int *Base; //数组头指针 int front; //对头 int rear; //队尾。。实际就是数组下标 int size; //队列长度 }Queue; void InitQueue(Queue *q, int size) { q->size = size; q->Base = (int *)malloc(sizeof(int)*q->size); //分配内存空间 if(NULL == q->Base) { printf("failed!\n"); exit(-1); } q->front = 0; q->rear = 0; //初始化队列里没有元素 下标为0 }void DestroyQueue(Queue *q) { q->front = 0; q->rear = 0; q->size = 0; free(q->Base); //回收空间 q->Base = NULL; }void clearQueue(Queue *q) { q->front = 0; q->rear = 0; }bool isEmpty(Queue *q) { if(q->front == q->rear ) {//空队列里面肯定头尾在一起 printf("empty!\n"); return true; }else return false; } bool isFull(Queue *q) { if((q->rear+1)%q->size == q->front) { // 循环队列当取余头尾相等时代表队列已满,+1代表空余一个就表示已满否则取余就无意思 printf("Full!\n"); return true; } else return false; } bool getHead(Queue *q, int *e) { if(isEmpty(q)) { printf("no head element\n"); return false; }else { *e = q->Base[q->front]; printf("the head is :%d\n ",*e); return true; } }int length(Queue *q) { return (q->rear - q->front +q->size) % q->size; // return (q->rear - q->front ) % q->size; //这样容易造成长度为负数(因为是循环队列 对头队尾不知道那个比较大) } //出对入队只要记着队尾入队,对头出对即可。 bool enQueue(Queue *q, int item) { if(isFull(q)){ return false; } else { q->Base[q->rear] = item; q->rear = (q->rear +1)% q->size; } return true; } bool deQueue(Queue *q, int *item) { if(isEmpty(q)) return false; else { *item = q->Base[q->front]; q->front = (q->front+1) % q->size; } return true; } //测试程序 int main() { int temp; Queue q; InitQueue(&q,5); printf("%d\n",isEmpty(&q)); enQueue(&q,1); deQueue(&q,&temp); enQueue(&q,2); enQueue(&q,8); deQueue(&q,&temp); enQueue(&q,18); enQueue(&q,3); deQueue(&q,&temp); enQueue(&q,4); enQueue(&q,5); printf("the length:%d \n",length(&q)); int a; getHead(&q,&a); for(int i =1 ; i <=4; i++) { int item; deQueue(&q,&item); printf("%d ",item); } DestroyQueue(&q); //队列已经销毁 任何操作都没用了 //enQueue(&q,1); getHead(&q,&a); return 0; }




    推荐阅读