【十二】队列及其顺序存储结构
2015-05-30 21:46
288 查看
1、队列的定义
队列是一种特殊的线性表
队列仅在线性表的两端进行操作
队头( Front):取出数据元素的一端
队尾( Rear):插入数据元素的一端
队列不允许在中间部位进行操作!
2、队列的性质
性质:先进先出(FIFO)
3、队列的顺序存储实现
示意图:
4、代码复用
利用顺序链表,实现顺序存储的队列!
经过时间复杂度的分析,常用操作SeqQueue_Append();的时间复杂度为O(1),但是SeqQueue_Retrieve();操作的时间复杂度却是O(n),所以有了以下改进的算法!
5、顺序队列的优化方案
SeqQueue_Retrieve();操作,因为删除的是顺序链表的第1个元素,所以每次都需要把后面的元素依次向前移动一位,这就增加了时间复杂度!
定义front使其始终代表队头的下标
出队时将队头元素返回,且front++
定义rear使其始终代表队尾下一个元素的下标
入队时将新元素插入,且rear++
没有必要只将下标为0的位置定义为队头!!!
6、改进的算法
数据结构的定义:
部分代码:
7、完整源码下载
文件名:seqqueue-1.0.tar.gz
说明:利用顺序链表实现的顺序队列
链接: http://pan.baidu.com/s/1kTnDpaf 密码: b7di
文件名:seqqueue-2.0.tar.gz
说明:未使用顺序链表,采用改进的算法重新实现的顺序队列
链接: http://pan.baidu.com/s/1i3Ij6g1 密码: eixe
编译步骤:
0.1 解压缩:tar -zxvf seqqueue-1.0.tar.gz/seqqueue-2.0.tar.gz
0.2 进入目录:./configure
0.3 生成Seqlist:make
0.4 运行程序:./SeqQueue
队列是一种特殊的线性表
队列仅在线性表的两端进行操作
队头( Front):取出数据元素的一端
队尾( Rear):插入数据元素的一端
队列不允许在中间部位进行操作!
2、队列的性质
性质:先进先出(FIFO)
3、队列的顺序存储实现
示意图:
4、代码复用
利用顺序链表,实现顺序存储的队列!
/* 在队尾添加一个元素 如果成功,返回1,失败返回0 */ int SeqQueue_Append(SeqQueue *queue, SeqQueueNode *item) //O(1) { //将线性表的尾部定义为队列的尾部 return List_Insert(queue,item,List_Length(queue)); } /* 在队头移出一个元素 如果成功,返回被移出的元素指针,否则,返回NULL */ SeqQueueNode *SeqQueue_Retrieve(SeqQueue *queue) //O(n) { return List_Delete(queue,0); }
经过时间复杂度的分析,常用操作SeqQueue_Append();的时间复杂度为O(1),但是SeqQueue_Retrieve();操作的时间复杂度却是O(n),所以有了以下改进的算法!
5、顺序队列的优化方案
SeqQueue_Retrieve();操作,因为删除的是顺序链表的第1个元素,所以每次都需要把后面的元素依次向前移动一位,这就增加了时间复杂度!
定义front使其始终代表队头的下标
出队时将队头元素返回,且front++
定义rear使其始终代表队尾下一个元素的下标
入队时将新元素插入,且rear++
没有必要只将下标为0的位置定义为队头!!!
6、改进的算法
数据结构的定义:
/* 为了保持对外的接口一致 */ typedef void SeqQueue; typedef void SeqQueueNode;
/* 内部实现的具体定义 */ #ifdef WIN32 typedef unsigned int TSeqQueueNode; #else typedef unsigned long TSeqQueueNode; #endif //增加了front和rear成员,用于标记队头和队尾 typedef struct _struct_SeqQueue { int capacity; int length; int front; int rear; TSeqQueueNode *node; }TSeqQueue;
部分代码:
/* 在队尾添加一个元素 如果成功,返回1,失败返回0 */ int SeqQueue_Append(SeqQueue *queue, SeqQueueNode *item) //O(1) { int iret = 1; TSeqQueue *tqueue = (TSeqQueue*)queue; iret = iret && (tqueue != NULL) && (item != NULL); if(iret) { //判断是否有位置可以插入 iret = tqueue->length < tqueue->capacity; if(iret) { //在当前队尾的位置插入数据,注意保存的是地址值 tqueue->node[tqueue->rear] = (TSeqQueueNode)item; //让队尾向后移动一个位置,如果超出数组,则重新指向0号位置 //此时数组是循环利用的 tqueue->rear = (tqueue->rear + 1) % tqueue->capacity; tqueue->length++; } } return iret; } /* 在队头移出一个元素 如果成功,返回被移出的元素指针,否则,返回NULL */ SeqQueueNode *SeqQueue_Retrieve(SeqQueue *queue) //O(1) { TSeqQueueNode *ret = NULL; TSeqQueue *tqueue = (TSeqQueue*)queue; if(tqueue != NULL) { //判断是否还有元素可取 if(tqueue->length > 0) { ret = (SeqQueueNode*)tqueue->node[tqueue->front]; //让队头向后移动一个位置,如果超出了数组,则指向0号位置 tqueue->front = (tqueue->front + 1) % tqueue->capacity; tqueue->length--; } } return ret; }
7、完整源码下载
文件名:seqqueue-1.0.tar.gz
说明:利用顺序链表实现的顺序队列
链接: http://pan.baidu.com/s/1kTnDpaf 密码: b7di
文件名:seqqueue-2.0.tar.gz
说明:未使用顺序链表,采用改进的算法重新实现的顺序队列
链接: http://pan.baidu.com/s/1i3Ij6g1 密码: eixe
编译步骤:
0.1 解压缩:tar -zxvf seqqueue-1.0.tar.gz/seqqueue-2.0.tar.gz
0.2 进入目录:./configure
0.3 生成Seqlist:make
0.4 运行程序:./SeqQueue
相关文章推荐
- DFS&Iteration Binary Tree Postorder Traversal
- HDU--3333(树状数组+离线处理)
- [Swust OJ 1139]--Coin-row problem
- Joel 技术分享心得
- 【PS后期】一个蛋糕的故事
- Android 中双击退出
- Android 记录2 对于Android事件分发的理解
- JavaScript 开发的45个经典技巧
- 【末世旅行之C++】C++中的虚函数和纯虚函数的理解
- iOS layoutSubviews视图重绘总结
- 编程之美第二题 找连续数
- 观察者模式
- 设计模式——外观模式
- spring 中 applicationEvent的使用
- openlayers实现wfs属性查询和空间查询
- openlayers实现wfs属性查询和空间查询
- PHP Cookies
- PHP Cookies
- slf4j使用
- MZOI-一个人的旅行