[置顶] ※数据结构※→☆线性表结构(queue)☆============队列 顺序存储结构(queue sequence)(八)
队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
在队列这种数据结构中,最先插入的元素将是最先被删除的元素;反之最后插入的元素将是最后被删除的元素,因此队列又称为“先进先出”(FIFO—first in first out)的线性表。
队列(Queue)是只允许在一端进行插入,而在另一端进行删除的运算受限的线性表
(1)允许删除的一端称为队头(Front)。
(2)允许插入的一端称为队尾(Rear)。
(3)当队列中没有元素时称为空队列。
(4)队列亦称作先进先出(First In First Out)的线性表,简称为FIFO表。
队列的修改是依先进先出的原则进行的。新来的成员总是加入队尾(即不允许"加塞"),每次离开的成员总是队列头上的(不允许中途离队),即当前"最老的"成员离队。
顺序存储结构
在计算机中用一组地址连续的存储单元依次存储线性表的各个数据元素,称作线性表的顺序存储结构.
顺序存储结构是存储结构类型中的一种,该结构是把逻辑上相邻的节点存储在物理位置上相邻的存储单元中,结点之间的逻辑关系由存储单元的邻接关系来体现。由此得到的存储结构为顺序存储结构,通常顺序存储结构是借助于计算机程序设计语言(例如c/c++)的数组来描述的。
顺序存储结构的主要优点是节省存储空间,因为分配给数据的存储单元全用存放结点的数据(不考虑c/c++语言中数组需指定大小的情况),结点之间的逻辑关系没有占用额外的存储空间。采用这种方法时,可实现对结点的随机存取,即每一个结点对应一个序号,由该序号可以直接计算出来结点的存储地址。但顺序存储方法的主要缺点是不便于修改,对结点的插入、删除运算时,可能要移动一系列的结点。
优点:
随机存取表中元素。缺点:插入和删除操作需要移动元素。
本代码默认list可以容纳的item数目为100个,用户可以自行设置item数目。当list饱和时,会自动以2倍的长度进行递增。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
以后的笔记潇汀会尽量详细讲解一些相关知识的,希望大家继续关注我的博客。
本节笔记到这里就结束了。
潇汀一有时间就会把自己的学习心得,觉得比较好的知识点写出来和大家一起分享。
编程开发的路很长很长,非常希望能和大家一起交流,共同学习,共同进步。
如果文章中有什么疏漏的地方,也请大家指正。也希望大家可以多留言来和我探讨编程相关的问题。
最后,谢谢你们一直的支持~~~
C++完整个代码示例(代码在VS2005下测试可运行)
AL_QueueSeq.h
/**
@(#)$Id: AL_QueueSeq.h 35 2013-09-06 08:47:50Z xiaoting $
@brief A queue is a special linear form, so special is that it only allows the front end of the table (front) delete operation,
and the rear end of the table (rear) for insertion, and the stack, as the queue is an operating by restricted linear form. Insert
operation is called the tail end, the end delete operation called HOL. No element in the queue, it is called an empty queue. This data structure in the queue, the first element inserted will be the first element to be removed; otherwise the last inserted
element will be the last element to be removed, so the queue is also known as "first in first out" (FIFO-first in first out) linear
form. ////////////////////////////////Sequential storage structure//////////////////////////////////////////
Using a set of addresses in the computer storage unit sequentially stores continuous linear form of individual data elements, called
the linear order of the table storage structure. Sequential storage structure is a type of a storage structure, the structure is the logically adjacent nodes stored in the physical
location of the adjacent memory cells, the logical relationship between nodes from the storage unit to reflect the adjacency.
Storage structure thus obtained is stored in order structure, usually by means of sequential storage structure computer programming
language (e.g., c / c) of the array to describe. The main advantage of the storage structure in order to save storage space, because the allocation to the data storage unit storing
all nodes with data (without regard to c / c language in the array size required for the case), the logical relationship between
the nodes does not take additional storage space. In this method, the node can be realized on a random access, that is, each node
corresponds to a number, the number can be calculated directly from the node out of the memory address. However, the main
disadvantage of sequential storage method is easy to modify the node insert, delete operations, may have to move a series of nodes.
Benefits:
Random Access table elements. Disadvantages: insert and delete operations need to move elements. @Author $Author: xiaoting $
@Date $Date: 2013-09-06 16:47:50 +0800 (周五, 06 九月 2013) $
@Revision $Revision: 35 $
@URL $URL: https://svn.code.sf.net/p/xiaoting/game/trunk/MyProject/AL_DataStructure/groupinc/AL_QueueSeq.h $
@Header $Header: https://svn.code.sf.net/p/xiaoting/game/trunk/MyProject/AL_DataStructure/groupinc/AL_QueueSeq.h 35 2013-09-06 08:47:50Z xiaoting $
*/ #ifndef CXX_AL_QUEUESEQ_H
#define CXX_AL_QUEUESEQ_H ///////////////////////////////////////////////////////////////////////////
// AL_QueueSeq
/////////////////////////////////////////////////////////////////////////// template<typename T>
class AL_QueueSeq
{
public:
static const DWORD QUEUESEQ_DEFAULTSIZE = 100;
static const DWORD QUEUESEQ_MAXSIZE = 0xffffffff;
/**
* Construction
*
* @param DWORD dwSize (default value: STACKSEQ_DEFAULTSIZE)
* @return
* @note
* @attention
*/
AL_QueueSeq(DWORD dwSize = QUEUESEQ_DEFAULTSIZE); /**
* Destruction
*
* @param
* @return
* @note
* @attention
*/
~AL_QueueSeq(); /**
* Empty
*
* @param VOID
* @return BOOL
* @note Returns true queue is empty
* @attention
*/
BOOL Empty() const; /**
* Front
*
* @param VOID
* @return T
* @note Returns a reference to the first element at the front of the queue.
* @attention
*/
T Front() const; /**
* Back
*
* @param VOID
* @return T
* @note Returns a reference to the last and most recently added element at the back of the queue.
* @attention
*/
T Back() const; /**
* Pop
*
* @param VOID
* @return T
* @note Removes an element from the front of the queue.
* @attention
*/
T Pop(); /**
* Push
*
* @param VOID
* @return DWORD
* @note Adds an element to the back of the queue.
* @attention
*/
VOID Push(const T& tTemplate); /**
* Size
*
* @param VOID
* @return DWORD
* @note Returns the number of elements in the queue
* @attention
*/
DWORD Size() const; /**
* Clear
*
* @param VOID
* @return VOID
* @note clear all data
* @attention
*/
VOID Clear(); protected:
private:
/**
* GetBuffer
*
* @param VOID
* @return VOID
* @note get the work buffer
* @attention when the buffer is not enough, it will become to double
*/
VOID GetBuffer(); /**
* IsFull
*
* @param VOID
* @return BOOL
* @note the buffer is full?
* @attention
*/
BOOL IsFull() const; public:
protected:
private:
T* m_pElements;
DWORD m_dwMaxSize;
DWORD m_dwSize; DWORD m_dwFront;
DWORD m_dwRear;
}; /**
* Construction
*
* @param DWORD dwSize (default value: STACKSEQ_DEFAULTSIZE)
* @return
* @note
* @attention
*/
template<typename T>
AL_QueueSeq<T>::AL_QueueSeq(DWORD dwSize):
m_pElements(NULL),
m_dwMaxSize(dwSize),
m_dwSize(0x00),
m_dwFront(0x00),
m_dwRear(0x00)
{
if (0x00 == m_dwMaxSize) {
//for memory deal
m_dwMaxSize = 1;
}
GetBuffer();
} /**
* Destruction
*
* @param
* @return
* @note
* @attention
*/
template<typename T>
AL_QueueSeq<T>::~AL_QueueSeq()
{
if (NULL != m_pElements) {
delete[] m_pElements;
m_pElements = NULL;
}
} /**
* Empty
*
* @param VOID
* @return BOOL
* @note Returns true queue is empty
* @attention
*/
template<typename T> BOOL
AL_QueueSeq<T>::Empty() const
{
return (0x00 == m_dwSize) ? TRUE:FALSE;
} /**
* Front
*
* @param VOID
* @return T
* @note Returns a reference to the first element at the front of the queue.
* @attention
*/
template<typename T> T
AL_QueueSeq<T>::Front() const
{
T tTypeTemp;
memset(&tTypeTemp, 0x00, sizeof(T)); if (TRUE ==Empty()) {
return tTypeTemp;
} return m_pElements[m_dwFront];
} /**
* Back
*
* @param VOID
* @return T
* @note Returns a reference to the last and most recently added element at the back of the queue.
* @attention
*/
template<typename T> T
AL_QueueSeq<T>::Back() const
{
T tTypeTemp;
memset(&tTypeTemp, 0x00, sizeof(T)); if (TRUE ==Empty()) {
return tTypeTemp;
} return m_pElements[m_dwRear];
} /**
* Pop
*
* @param VOID
* @return T
* @note Removes an element from the front of the queue.
* @attention
*/
template<typename T> T
AL_QueueSeq<T>::Pop()
{
T tTypeTemp;
memset(&tTypeTemp, 0x00, sizeof(T)); if (TRUE ==Empty()) {
return tTypeTemp;
}
tTypeTemp = m_pElements[m_dwFront];
memset(&m_pElements[m_dwFront], 0x00, sizeof(T)); m_dwFront++;
m_dwSize--;
return tTypeTemp;
} /**
* Push
*
* @param VOID
* @return DWORD
* @note Adds an element to the back of the queue.
* @attention
*/
template<typename T> VOID
AL_QueueSeq<T>::Push(const T& tTemplate)
{
if (TRUE == IsFull()) {
// full, need to get more work buffer
GetBuffer();
} if (0x00 == m_dwFront && TRUE == Empty()) {
//the first time Push, not need to ++
m_dwRear = 0x00;
}
else {
m_dwRear++;
}
m_pElements[m_dwRear] = tTemplate; m_dwSize++;
} /**
* Size
*
* @param VOID
* @return DWORD
* @note Returns the number of elements in the queue
* @attention
*/
template<typename T> DWORD
AL_QueueSeq<T>::Size() const
{
return m_dwSize;
} /**
* Clear
*
* @param VOID
* @return VOID
* @note clear all data
* @attention
*/
template<typename T> VOID
AL_QueueSeq<T>::Clear()
{
memset(m_pElements, 0x00, sizeof(T)*Size());
m_dwSize = 0x00;
m_dwFront = 0x00;
m_dwRear = 0x00;
} /**
* GetBuffer
*
* @param VOID
* @return VOID
* @note get the work buffer
* @attention when the buffer is not enough, it will become to double
*/
template<typename T> VOID
AL_QueueSeq<T>::GetBuffer()
{ if ( (FALSE == IsFull()) &&(NULL != m_pElements) ) {
//we do not need to get more buffer
return;
} if (NULL == m_pElements) {
if(0 < m_dwMaxSize){
//get the new work buffer
m_pElements = new T[m_dwMaxSize];
memset(m_pElements, 0x00, sizeof(T)*m_dwMaxSize);
}
return;
} //we need to get more buffer, store the previous pointer
T* pLastTpye = NULL;
DWORD pLastSize = 0x00; // it will become to double
pLastSize = m_dwMaxSize;
pLastTpye = m_pElements;
if (QUEUESEQ_MAXSIZE/2 < m_dwMaxSize) {
m_dwMaxSize = QUEUESEQ_MAXSIZE;
}
else {
m_dwMaxSize *= 2;
}
if(0 < m_dwMaxSize){
//get the new work buffer
m_pElements = new T[m_dwMaxSize];
memset(m_pElements, 0x00, sizeof(T)*m_dwMaxSize);
}
//need to copy the last to the current
memcpy(m_pElements, pLastTpye, sizeof(T)*pLastSize);
//free the last work buffer
delete[] pLastTpye;
pLastTpye = NULL;
} /**
* IsFull
*
* @param
* @return BOOL
* @note the buffer is full?
* @attention
*/
template<typename T> BOOL
AL_QueueSeq<T>::IsFull() const
{
return (m_dwMaxSize <= m_dwFront+Size()) ? TRUE:FALSE;
} #endif // CXX_AL_QUEUESEQ_H
/* EOF */
测试代码
#ifdef TEST_AL_QUEUESEQ
AL_QueueSeq<DWORD> cQueueSeq(1);
BOOL bEmpty = cQueueSeq.Empty();
std::cout<<bEmpty<<std::endl;
DWORD dwSize = cQueueSeq.Size();
std::cout<<dwSize<<std::endl;
DWORD dwFront = cQueueSeq.Front();
std::cout<<dwFront<<std::endl;
DWORD dwBack = cQueueSeq.Back();
std::cout<<dwBack<<std::endl;
DWORD dwPop = cQueueSeq.Pop();
std::cout<<dwPop<<std::endl; cQueueSeq.Push(999);
bEmpty = cQueueSeq.Empty();
std::cout<<bEmpty<<std::endl;
dwSize = cQueueSeq.Size();
std::cout<<dwSize<<std::endl;
dwFront = cQueueSeq.Front();
std::cout<<dwFront<<std::endl;
dwBack = cQueueSeq.Back();
std::cout<<dwBack<<std::endl;
dwPop = cQueueSeq.Pop();
std::cout<<dwPop<<std::endl; for (DWORD dwCnt=1; dwCnt<16; dwCnt++) {
cQueueSeq.Push(dwCnt);
dwBack = cQueueSeq.Back();
std::cout<<dwBack<<std::endl;
} dwSize = cQueueSeq.Size();
std::cout<<dwSize<<std::endl;
dwFront = cQueueSeq.Front();
std::cout<<dwFront<<std::endl; while (0x00 != cQueueSeq.Size()) {
dwPop = cQueueSeq.Pop();
std::cout<<dwPop<<std::endl;
} bEmpty = cQueueSeq.Empty();
std::cout<<bEmpty<<std::endl;
dwSize = cQueueSeq.Size();
std::cout<<dwSize<<std::endl;
dwFront = cQueueSeq.Front();
std::cout<<dwFront<<std::endl;
dwBack = cQueueSeq.Back();
std::cout<<dwBack<<std::endl;
dwPop = cQueueSeq.Pop();
std::cout<<dwPop<<std::endl; #endif
[置顶] ※数据结构※→☆线性表结构(queue)☆============队列 顺序存储结构(queue sequence)(八)的更多相关文章
- [置顶] ※数据结构※→☆线性表结构(queue)☆============循环队列 顺序存储结构(queue circular sequence)(十)
循环队列 为充分利用向量空间,克服"假溢出"现象的方法是:将向量空间想象为一个首尾相接的圆环,并称这种向量为循环向量.存储在其中的队列称为循环队列(Circular Queue). ...
- [置顶] ※数据结构※→☆线性表结构(queue)☆============优先队列 链式存储结构(queue priority list)(十二)
优先队列(priority queue) 普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除.在优先队列中,元素被赋予优先级.当访问元素时,具有最高优先级的元素最先删除.优先队列具有 ...
- [置顶] ※数据结构※→☆线性表结构(stack)☆============栈 序列表结构(stack sequence)(六)
栈(stack)在计算机科学中是限定仅在表尾进行插入或删除操作的线性表.栈是一种数据结构,它按照后进先出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据.栈 ...
- [置顶] ※数据结构※→☆线性表结构(list)☆============单向链表结构(list single)(二)
单向链表(单链表)是链表的一种,其特点是链表的链接方向是单向的,对链表的访问要通过顺序读取从头部开始:链表是使用指针进行构造的列表:又称为结点列表,因为链表是由一个个结点组装起来的:其中每个结点都有指 ...
- [置顶] ※数据结构※→☆线性表结构(list)☆============双向链表结构(list double)(三)
双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点. ~~~~~~~~~~~~ ...
- 数据结构----线性表顺序和链式结构的使用(c)
PS:在学习数据结构之前,我相信很多博友也都学习过一些语言,比如说java,c语言,c++,web等,我们之前用的一些方法大都是封装好的,就java而言,里面使用了大量的封装好的方法,一些算法也大都写 ...
- [从今天开始修炼数据结构]线性表及其实现以及实现有Itertor的ArrayList和LinkedList
一.线性表 1,什么是线性表 线性表就是零个或多个数据元素的有限序列.线性表中的每个元素只能有零个或一个前驱元素,零个或一个后继元素.在较复杂的线性表中,一个数据元素可以由若干个数据项组成.比如牵手排 ...
- [数据结构-线性表1.2] 链表与 LinkedList<T>(.NET 源码学习)
[数据结构-线性表1.2] 链表与 LinkedList<T> [注:本篇文章源码内容较少,分析度较浅,请酌情选择阅读] 关键词:链表(数据结构) C#中的链表(源码) 可空类 ...
- C# 数据结构 线性表(顺序表 链表 IList 数组)
线性表 线性表是最简单.最基本.最常用的数据结构.数据元素 1 对 1的关系,这种关系是位置关系. 特点 (1)第一个元素和最后一个元素前后是没有数据元素,线性表中剩下的元素是近邻的,前后都有元素. ...
随机推荐
- 我的Python成长之路---第四天---Python基础(16)---2016年1月23日(寒风刺骨)
四.正则表达式 字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在.比如判断一个字符串是否是合法的Email地址,虽然可以编程提取@前后的子串,再分别判断是否是单词和 ...
- POJ2728 最小比率生成树/0-1分数规划/二分/迭代(迭代不会)
用01分数规划 + prime + 二分 竟然2950MS惊险的过了QAQ 前提是在TLE了好几次下过的 = = 题目意思:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一 ...
- (Problem 4)Largest palindrome product
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2 ...
- Chapter 14 观察者模式
观察者模式又叫做发布-订阅模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己. 观察者模式所做的工作其 ...
- ognl中的#、%和$
多学点,谢谢兄弟 原文地址:ognl中的#.%和$作者:百合 ognl中的#.%和$ #.%和$符号在OGNL表达式中经常出现,而这三种符号也是开发者不容易掌握和理解的部分.在这里笔者简单介绍它们的相 ...
- Linux内核空间-用户空间通信之debugfs
一.debugfs文件系统简介 debugfs虚拟文件系统是一种内核空间与用户空间的接口,基于libfs库实现,专用于开发人员调试,便于向用户空间导出内核空间数据(当然,反方向也可以).debugfs ...
- DockerCon 2016
DockerCon 2016 – 微软带来了什么? 根据Forrester的调查,接近半数的企业CIO在考虑IT架构的时候更乐于接受开源方案,这主要是基于低成本,避免供应商锁定和敏捷的需求:同时另 ...
- JVM调优总结(十一)-反思
垃圾回收的悖论 所谓“成也萧何败萧何”.Java的垃圾回收确实带来了很多好处,为开发带来了便利.但是在一些高性能.高并发的情况下,垃圾回收确成为了制约Java应用的瓶颈.目前JDK的垃圾回收算法,始终 ...
- Linux 命令整理
一.文件目录命令 1.建立目录:mkdir 目录名 2.删除空目录:rmdir 目录名 3.无条件删除子目录: rm -rf 目录名 4.改变当前目录:cd 目录名 (进入用户home目录:cd ~; ...
- -F, --flush-logs
<pre name="code" class="html"> -F, --flush-logs Flush logs file in server ...