C++实现的一个循环队列

工作之余写的一个简单的循环队列模板类。为什么要用循环队列呢? 因为它省去了元素拷贝的开销,众所周知,拷贝元素是很耗时,会比较影响效率,

特别是大规模的拷贝,更是如此。相比较直队列,循环队列不需要在头部元素被取出时,需要将后面的元素向头部移动的操作,因此可以说省时省力,

对效率而言,也是个比较大的提升~~

共有4个程序文件: common_type.h  common_struct.h  common_queue.h   main.cpp  

外加一个编译用的文件: Makefile  


//file: common_struct.h

/*********************************************
* filename: common_struct.h
* date: 2014-07-23 10:24
* author: jackie
* desc: define struct used in program
*********************************************/
#ifndef COMMON_STRUCT_H
#define COMMON_STRUCT_H

#include <stdio.h>
#include <stdlib.h>
#include <string>

#include "common_type.h"

typedef struct STC_LOG
{
std::string time;
std::string content;
uint32_t level;

STC_LOG& operator=(const STC_LOG& obj)
{
this->time = obj.time;
this->content = obj.content;
this->level = obj.level;

return *this;
}

STC_LOG()
{
time.clear();
content.clear();
level = 0;
}

~STC_LOG()
{
time.clear();
content.clear();
level = 0;
}

void show()
{
printf("loginfo time=%s, content=%s, level=%d\n", time.c_str(), content.c_str(), level);
}

}STC_LOG;

#endif


//file: common_type.h

/***********************************************************
* filename: common_type.h
* date: 2014-07-23 10:28
* author: jackie
* desc: define data type which is more convenient to use
***********************************************************/
#ifndef COMMON_TYPE_H
#define COMMON_TYPE_H

typedef int  int32_t;
typedef unsigned int uint32_t;

#endif


//file: common_queue.h

/************************************************************
** filename: common_queue.h
** date: 2014-07-22 22:32
** author: jackie
** desc: 实现一个循环队列模板
************************************************************/
#ifndef BASE_CIRCLE_QUEUE_T_H
#define BASE_CIRCLE_QUEUE_T_H

#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include "common_type.h"

static const uint32_t min_free_size = 2;

template<typename T, uint32_t SIZE>
class CCommonQueue_T
{
public:
CCommonQueue_T()
{
printf("begin constructor\n");
Init(SIZE);
printf("end constructor\n");
}


virtual ~CCommonQueue_T()
{
printf("begin deconstruct\n");
if(m_arrBuf)
{
delete []m_arrBuf;
}

m_uHead = 0;
m_uTail = 0;
m_uMaxBufLen = 0;
printf("end deconstruct\n");
}

void Init(const uint32_t size)
{
m_uMaxBufLen = size;
m_arrBuf = new T[m_uMaxBufLen];
m_uHead = 0;
m_uTail = 0;
for(uint32_t i=0; i<m_uMaxBufLen; i++)
{
m_vecMark.push_back(0);
}

}

bool Empty()
{
if( m_uHead == m_uTail)
{
return true;
}


return false;
}

bool Full()
{
uint32_t left = 0;
if( m_uTail >= m_uHead )
{
left = m_uMaxBufLen - ( m_uTail - m_uHead );
}


if( m_uTail < m_uHead )
{
left = m_uHead - m_uTail;
}


//留8个位置空闲【防止追尾情况】
if( left <= min_free_size )
{
return true;
}

return false;
}

//向队列中添加一个元素
uint32_t Push(const T& obj)
{
if( Full() )
{
return 1;
}
m_arrBuf[m_uTail] = obj;
m_vecMark[m_uTail] = 1;
m_uTail += 1;
if( m_uTail >= m_uMaxBufLen )
{
m_uTail = 0;
}

return 0;
}

//从队列中取出一个元素
uint32_t Pop(T& obj)
{
if( Empty() )
{
return 1;
}

obj = m_arrBuf[m_uHead];
m_vecMark[m_uHead] = 0;
m_uHead += 1;
if( m_uHead >= m_uMaxBufLen )
{
m_uHead = 0;
}

return 0;
}

//获取队列元素个数
uint32_t ElemCount()
{
if( m_uTail >= m_uHead )
{
return (m_uTail - m_uHead);
}

if( m_uTail < m_uHead )
{
return (m_uMaxBufLen - ( m_uHead - m_uTail ) );
}

return 0;
}

void show()
{
for(uint32_t i=0; i<m_uMaxBufLen; i++)
{
if( m_vecMark[i] == 0 )
{
printf("pos %d have no element\n", i);
continue;
}

printf("pos %d element is: ", i);
m_arrBuf[i].show();
}
}

uint32_t Head()
{
return m_uHead;
}

uint32_t Tail()
{
return m_uTail;
}

private:
//貌似这里用vector是一个比较好的方法:可以比较一下两者的效率:即用数组和vector做一个对比
//std::vector<T> m_vecElem;  
T* m_arrBuf;
std::vector<uint32_t> m_vecMark;
uint32_t m_uMaxBufLen;
uint32_t m_uHead;
uint32_t m_uTail;
};

#endif


//file: main.cpp

/*******************************************
* filename: main.cpp
* date: 2014-07-23 10:21
* author: jackie
* desc: function entrance
*******************************************/
#include "common_queue.h"
#include "common_struct.h"

int main()
{
CCommonQueue_T<STC_LOG, 10> logQueue;


uint32_t count = logQueue.ElemCount();
printf("common queue element count=%d\n", count);


for(uint32_t i=0; i<10; i++)
{
STC_LOG log;
std::string num;
char arr[10];
sprintf(arr, "%2d", i);
num = arr;
log.time = "2014-07-23 11:15:00";
log.content = "log index " + num;
log.level = 0;

uint32_t ret = 0;
ret = logQueue.Push(log);
if( ret > 0 )
{
printf("push element failed, errorcode=%d\n", ret);
}
}


for(uint32_t i=0; i<5; i++)
{
STC_LOG log;
uint32_t ret = 0;
ret = logQueue.Pop(log);
if( ret > 0 )
{
printf("pop element failed\n");
}


//log.show();
}




for(uint32_t i=0; i<10; i++)
{
STC_LOG log;
std::string num;
char arr[10];
sprintf(arr, "%2d", i);
num = arr;
log.time = "2014-07-23 11:15:00";
log.content = "log index " + num;
log.level = 0;

uint32_t ret = 0;
ret = logQueue.Push(log);
if( ret > 0 )
{
printf("push element failed, errorcode=%d\n", ret);
}
}


logQueue.show();
printf("head=%u, tail=%u\n", logQueue.Head(), logQueue.Tail());

printf("common queue test\n");
return 0;
}


//file: Makefile

TARGET:=common
INCDIR:=inc
##SRCDIR:=src
SRCDIR:=./
OBJDIR:=obj
$(shell if !([ -d $(OBJDIR) ]);then mkdir $(OBJDIR);fi)
LIBDIR:=lib
$(shell if !([ -d $(LIBDIR) ]);then mkdir $(LIBDIR);fi)

CC  :=g++

FLAGS:=-Wall -W -I$(INCDIR) -D_DEBUG
LIBS :=-lpthread

##OPENCV=1 #switch of opencv
##ifdef OPENCV
##FLAGS+=`pkg-config --cflags opencv`
##LIBS +=`pkg-config --libs opencv`
##endif

#DBG=0
##ifdef DBG
FLAGS=-g -Wall
##else
##FLAGS+=-O2
##endif

## define lib
LIBS=-lpthread

##echo "include dir"
SRC:=$(wildcard $(SRCDIR)/*.cpp)
OBJ:=$(patsubst %.cpp,$(OBJDIR)/%.o,$(notdir $(SRC)))

#all:
#    @echo $(OBJ)
#

$(TARGET):$(OBJ)
$(CC) -o $@ $^ $(FLAGS) $(LIBS)
$(OBJDIR)/%.o:$(SRCDIR)/%.cpp 
$(CC) -c $< -o $@ $(FLAGS)
.PHONY: clean
clean:
rm -f $(OBJDIR)/*.o *~ core $(TARGET)


编译方法:

xiaoheqing@xiaoheqing-VirtualBox:~/mytest/muding$  make

执行程序:

xiaoheqing@xiaoheqing-VirtualBox:~/mytest/muding$  ./common

输出如下:

begin constructor
end constructor
common queue element count=0
push element failed, errorcode=1
push element failed, errorcode=1
push element failed, errorcode=1
push element failed, errorcode=1
push element failed, errorcode=1
push element failed, errorcode=1
push element failed, errorcode=1
pos 0 element is: loginfo time=2014-07-23 11:15:00, content=log index  2, level=0
pos 1 element is: loginfo time=2014-07-23 11:15:00, content=log index  3, level=0
pos 2 element is: loginfo time=2014-07-23 11:15:00, content=log index  4, level=0
pos 3 have no element
pos 4 have no element
pos 5 element is: loginfo time=2014-07-23 11:15:00, content=log index  5, level=0
pos 6 element is: loginfo time=2014-07-23 11:15:00, content=log index  6, level=0
pos 7 element is: loginfo time=2014-07-23 11:15:00, content=log index  7, level=0
pos 8 element is: loginfo time=2014-07-23 11:15:00, content=log index  0, level=0
pos 9 element is: loginfo time=2014-07-23 11:15:00, content=log index  1, level=0
head=5, tail=3
common queue test
begin deconstruct
end deconstruct


可以看到,程序实现了循环队列的效果,头和尾之间留两个单位的空闲,防止追尾【单位指的是模板中数据类型T】


















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值