目录
一 、链队列
二 、循环队列
三、总结&反思
一 、链队列
队列是相对于栈来说的一种数据结构,是一种先进先出的方式。类似于我们正常的排队,队列的实现方式同样有顺序式和链式。这里我们展示一下链式的代码
#include#include //链表中的节点结构 typedef struct QNode { int data; struct QNode *next; } QNode; //创建链式队列的函数 QNode *initQueue() { //创建一个头节点 QNode *queue = (QNode *)malloc(sizeof(QNode)); //对头节点进行初始化 queue->next = NULL; return queue; } QNode *enQueue(QNode *rear, int data) { QNode *enElem = (QNode *)malloc(sizeof(QNode)); enElem->data = data; enElem->next = NULL; //使用尾插法向链队列中添加数据元素 rear->next = enElem; rear = enElem; return rear; } QNode *DeQueue(QNode *top, QNode *rear) { if (top->next == NULL) { printf("n队列为空"); return rear; } QNode *p = top->next; printf("出队的元素是:%d n", p->data); top->next = p->next; if (rear == p) { rear = top; } free(p); return rear; } //队列的长度 int QueueLength(QNode *top) { int length = 0; QNode *pMove = top; if (pMove->next == NULL) { //头指针指向空,长度为0 return length; } while (pMove->next != NULL) { //头指针不为空,移动指针计算长度 pMove = pMove->next; length++; } return length; } void printQueue(QNode *top) { QNode *pMove = top->next; if (pMove->next == NULL) { printf("该队列为空!n"); } while (pMove != NULL) { printf("%d ", pMove->data); pMove = pMove->next; } printf("n"); } int main() { QNode *queue, *top, *rear; queue = top = rear = initQueue(); //创建头结点 //向链队列中添加结点,使用尾插法添加的同时,队尾指针需要指向链表的最后一个元素 for (int i = 0; i < 10; i++) { rear = enQueue(rear, i + 1); } printQueue(top); printf("队列的长度为:%dn", QueueLength(top)); //入队完成,所有数据元素开始出队列 rear = DeQueue(top, rear); rear = DeQueue(top, rear); return 0; }
在老师的代码中,是重新定义了一个数据结构,这个数据结构包括两个节点指针,代表top&rear。当然,也可以手动定义两个指针,分别来表示,其实和我们之前学习到的链表很像很像的啦。
这里贴一下运行结果:
二 、循环队列
循环队列类似于循环链表,在解决约瑟夫环等相关问题上会有一些卓越的表现。代码实现的地方,最核心的就是注意判断下标,注意i%total_size。这样语句的应用。
上代码;
#include#include //循环队列 struct Queue { //结构体 int *data; int capacity; //最大容积 int front; //表头 int rear; //表尾 // int size; //size表示队列的现有容量, }; void init(struct Queue *pq, int capacity) { //队列的初始化 pq->capacity = capacity; pq->data = (int *)malloc(sizeof(int) * (capacity + 1)); pq->front = 0; //初始化的不同,会导致后面判断队列是否为空以及是否已满的不同 pq->rear = 0; } int isFull(const struct Queue *pq) { //判断队列是否已满 if ((pq->rear + 1) % (pq->capacity + 1) == pq->front) return 1; else return 0; } int isEmpty(const struct Queue *pq) { //判断是否为空 return pq->front == pq->rear; } int enQueue(struct Queue *pq, int x) { //入队操作 if (isFull(pq)) return 0; else { pq->data[pq->rear] = x; pq->rear = (pq->rear + 1) % (pq->capacity + 1); return 1; //成功返回1,失败返回0 } } int deQueue(struct Queue *pq, int *px) { //出队操作 if (isEmpty(pq)) return 0; else { *px = pq->data[pq->front]; pq->front = (pq->front + 1) % (pq->capacity + 1); return 1; //成功返回1,失败返回0 } } int main() { struct Queue q; init(&q, 4); enQueue(&q, 11); enQueue(&q, 22); enQueue(&q, 33); enQueue(&q, 44); enQueue(&q, 55); int x; deQueue(&q, &x); printf("%dn", x); deQueue(&q, &x); printf("%dn", x); deQueue(&q, &x); printf("%dn", x); deQueue(&q, &x); printf("%dn", x); deQueue(&q, &x); printf("%dn", x); }
三、总结&反思
就像老师之前说的那个样子,其实只要把线性表的入门做好了,尤其是明白链表的操作以及操作原理,其实后面的数据结构都还好说,都是一个样子,顺序的就用一个数组来实现,链式的就多搞几个指针即可。



