数据结构与算法分析学习笔记三-循环队列C语言实现
2013-11-24 10:02
351 查看
队列,在日常生活中有很多非常直观的例子。实际生活中的每次排队都是一个队列。今天我们就来看看循环队列的如何用简单的C语言来实现。本文中所有的代码均在anycodes.tk在线编程网站上测试通过。
队列进队,出对的操作实际上和前面讲过的栈差不多。只不过,栈进出在一端,而队列进出分别在队列的两端。所以一些基本的操作代码是非常容易看懂的,再次略过。本文着重分析在循环队列中如何进行错误控制,主要介绍两种方法。
1. 标志位法
这里所谓的标志位法,是指在结构体中添加一个成员变量Size,当有元素进队时,Size加一;反之,元素出对时,Size减一。因此可以通过Size和队列能容纳最多个元素Capacity比较,来确定队列满或队列空。详细见如下代码:
在anycodes.tk在线编程网站上的测试结果:
2. 使用Front和Rear联系
这里说的使用Front和Rear的联系来进行判断队空和队满是指,在循环队列中,Front = Rear时,无法判断队空还是队满,为了区别这一问题,当Front = Rear表示队空,而当(Rear+1)%N = Front时,表示队满,其中N表示队列中的空格个数。大家可以画一画图,其实这个时候在队列中有一个格子是空的。好,话不多少,直接看代码。
在anycodes.tk上的测试结果
大家可以对照测试结果图,或者自己去测试一下,帮助自己理解。
下一篇博客将是第四章树。加油加油!
队列进队,出对的操作实际上和前面讲过的栈差不多。只不过,栈进出在一端,而队列进出分别在队列的两端。所以一些基本的操作代码是非常容易看懂的,再次略过。本文着重分析在循环队列中如何进行错误控制,主要介绍两种方法。
1. 标志位法
这里所谓的标志位法,是指在结构体中添加一个成员变量Size,当有元素进队时,Size加一;反之,元素出对时,Size减一。因此可以通过Size和队列能容纳最多个元素Capacity比较,来确定队列满或队列空。详细见如下代码:
#include <stdio.h> #include <stdlib.h> #include <malloc.h> struct Queue; typedef struct Queue *pQueue; struct Queue { int Capacity; //队列中可容纳最大个数的元素 int Size; //队列中已有元素的个数 int Rear; //队列中进行数据插入的一端 int Front; //队列中进行数据删除的一端 int *Array; }; //创建队列 void createQueue(pQueue ptrQueue, int EleNum) { if (ptrQueue == NULL) { printf("Out of space!\n"); //分配空间失败 exit(1); } ptrQueue -> Array = malloc(sizeof(int)*(EleNum-1)); //给数组分配空间 if (ptrQueue -> Array == NULL) { printf("Out of space!\n"); //分配空间失败 exit(1); } ptrQueue -> Capacity = EleNum; ptrQueue -> Size = 0; ptrQueue -> Rear = 0; ptrQueue -> Front = 0; } int isFull(pQueue ptrQueue) { return ptrQueue -> Size == ptrQueue -> Capacity -1; } int calRearFront(int flag, pQueue ptrQueue) { if(++flag == ptrQueue -> Capacity) flag = 0; return flag; } void Enqueue(pQueue ptrQueue, int ele) { if(isFull(ptrQueue)) { printf("Sorry, the queue is full!\n"); exit(1); } ptrQueue -> Rear = calRearFront(ptrQueue->Rear, ptrQueue); ptrQueue -> Array[ptrQueue -> Rear] = ele; ptrQueue -> Size++; } int isEmpty(pQueue ptrQueue) { return ptrQueue -> Size == 0; } int Dequeue(pQueue ptrQueue) { int result; if(isEmpty(ptrQueue)) { printf("Sorry, the queue is blank!\n"); exit(1); } ptrQueue -> Front = calRearFront(ptrQueue -> Front, ptrQueue); result = ptrQueue -> Array[ptrQueue -> Front]; ptrQueue -> Size++; return result; } void freeStack(pQueue ptrQueue) { free(ptrQueue -> Array); free(ptrQueue); } int main() { int a[3] = {12,4354,657}; int i = 0; int topElement = 0; int result = 0; pQueue queue; queue = malloc(sizeof(struct Queue)); createQueue(queue,4); //创建队列 for (; i < 3; i++) { Enqueue(queue, a[i]); //插入数值 } //Enqueue(queue, 2); //队列满,报错直接退出 result = Dequeue(queue); //移除队列中的元素 printf("The dequeue element in the queue is %d!\n",result); freeStack(queue); return 0; }
在anycodes.tk在线编程网站上的测试结果:
2. 使用Front和Rear联系
这里说的使用Front和Rear的联系来进行判断队空和队满是指,在循环队列中,Front = Rear时,无法判断队空还是队满,为了区别这一问题,当Front = Rear表示队空,而当(Rear+1)%N = Front时,表示队满,其中N表示队列中的空格个数。大家可以画一画图,其实这个时候在队列中有一个格子是空的。好,话不多少,直接看代码。
#include <stdio.h> #include <stdlib.h> #include <malloc.h> struct Queue; typedef struct Queue *pQueue; struct Queue { int Capacity; //队列中可容纳最大个数的元素 //int Size; //队列中已有元素的个数 int Rear; //队列中进行数据插入的一端 int Front; //队列中进行数据删除的一端 int *Array; }; //创建队列 void createQueue(pQueue ptrQueue, int EleNum) { if (ptrQueue == NULL) { printf("Out of space!\n"); //分配空间失败 exit(1); } ptrQueue -> Array = malloc(sizeof(int)*(EleNum-1)); //给数组分配空间 if (ptrQueue -> Array == NULL) { printf("Out of space!\n"); //分配空间失败 exit(1); } ptrQueue -> Capacity = EleNum; // ptrQueue -> Size = 0; ptrQueue -> Rear = 0; ptrQueue -> Front = 0; } int isFull(pQueue ptrQueue) { return (ptrQueue -> Rear + 1) % (ptrQueue -> Capacity) == ptrQueue -> Front; } void Enqueue(pQueue ptrQueue, int ele) { if(isFull(ptrQueue)) { printf("Sorry, the queue is full!\n"); exit(1); } ptrQueue -> Rear++; ptrQueue -> Array[ptrQueue -> Rear] = ele; } int isEmpty(pQueue ptrQueue) { return ptrQueue -> Rear == ptrQueue -> Front; } int Dequeue(pQueue ptrQueue) { int result; if(isEmpty(ptrQueue)) { printf("Sorry, the queue is blank!\n"); exit(1); } ptrQueue -> Front++; result = ptrQueue -> Array[ptrQueue -> Front]; return result; } void freeQueue(pQueue ptrQueue) { free(ptrQueue -> Array); free(ptrQueue); } int main() { int a[3] = {12,4354,657}; int i = 0; int j = 0; int topElement = 0; int result = 0; pQueue queue; queue = malloc(sizeof(struct Queue)); createQueue(queue,4); //创建队列 for (; i < 3; i++) { Enqueue(queue, a[i]); //插入数值 } //printStack(s); // Enqueue(queue, 2); //队列满,报错直接退出 for (; j < 3; j++) { result = Dequeue(queue); //移除队列中的元素 printf("The dequeue element in the queue is %d!\n",result); } //printStack(s); Dequeue(queue); freeQueue(queue); return 0; }
在anycodes.tk上的测试结果
大家可以对照测试结果图,或者自己去测试一下,帮助自己理解。
下一篇博客将是第四章树。加油加油!
相关文章推荐
- 栈-顺序表实现
- 数据结构应用标准模版库STL——向量的操作(对排序后的子表进行排序)
- ccnu 十一月半月赛 F题 会攻击的点 - 离散化 + 区间求和
- 11.23数据结构----图的遍历/连通性
- 数据结构Java版例程练习
- 数据结构与算法分析学习笔记二-栈的C语言实现
- 数据结构学习笔记—图---图的连通性、顶点间的路径
- MySQL索引背后的数据结构及算法原理
- 关于Java的数据结构HashMap,ArrayList的使用总结及使用场景和原理分析
- 数据结构 队列的相关操作
- 斯坦福大学王颖 浅谈ACM ICPC的题目风格和acm比赛近几年
- Java进阶7并发优化4——JDK并发数据结构
- 欧拉回路
- 并查集
- 【索引】算法竞赛入门经典-第6章 数据结构基础
- 数据结构图的定义
- 查找的基本概念
- 动态查找
- 静态查找
- 邻接矩阵实现的广度优先搜索