您的位置:首页 > 其它

【十二】队列及其顺序存储结构

2015-05-30 21:46 288 查看
1、队列的定义

队列是一种特殊的线性表

队列仅在线性表的两端进行操作

队头( 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: