#ifndef __IRR_CHAIN_H_INCLUDED__
#define __IRR_CHAIN_H_INCLUDED__
#include <iostream>
template<typename T>
class Chain;
//=====================================Node====================================
template<typename T>
struct Node {
T data;
Node* next;
Node* pre;
};
//=====================================Block===================================
template<typename T>
class Block {
friend class Chain<T>;
public:
Block(int size) {
pool = new Node<T>[size];
next = 0;
for (int i = 1; i < size; i++) {//建立前赴后继关系
pool[i - 1].next = &pool[i];
pool[i].pre = &pool[i - 1];
}
}
private:
Node<T>* pool;
Block* next;
};
//===================================Iterator=================================
template<class T>
class ChainIterator {
public:
ChainIterator(Chain<T>* _container) {
container = _container;
cur = &(container->pool[0]);
}
//获取迭代器当前指向的元素
T const& get() {
return cur->data;
}
//重置迭代器,不指向任何元素
bool reset() {
cur = &(container->pool[0]);
}
//迭代器指向链首元素
bool first() {
if (container->getLength() == 0)
cur = &(container->pool[0]);
else {
cur = container->pool[0].next;
}
}
//迭代器指向链尾元素
void last() {
if (container->getLength() == 0)
cur = container->empty_head;
else {
cur = container->used_tail;
}
}
//是否越界,用来在循环中遍历元素用
bool isOver() {
if (cur == (container->empty_head)
|| cur == &(container->pool[0]))
return false;
else {
return true;
}
}
//迭代器指向下一个元素
void next() {
cur = cur->next;
}
//迭代器指向前一个元素
bool pre() {
cur = cur->pre;
}
//在当前元素之后插入一个元素,迭代器仍指向当前位置
void insert(T const& item) {
if (cur == container->used_tail) {
container->append(item);
} else {
Node<T>* temp = container->allocate();
temp->data = item;
temp->next = cur->next;
cur->next->pre = temp;
cur->next = temp;
temp->pre = cur;
}
}
//移除当前迭代器指向的元素,迭代器指向下一个元素
void remove() {
if (cur == container->used_tail) {
container->pop();
cur = container->used_tail;
} else {
Node<T>* temp = cur->next;
container->deallocate(cur);
cur = temp;
}
}
private:
Node<T>* cur;
Chain<T>* container;
};
//===================================Chain=================================
template<typename T>
class Chain {
friend class ChainIterator<T>;
public:
typedef ChainIterator<T> Iterator;
Chain(int size = 20) {
blockSize = size + 2;
block = new Block<T > (blockSize);
pool = block->pool;
used_tail = &pool[0];
empty_head = &pool[1];
empty_tail = &pool[blockSize - 1];
length = 0;
}
~Chain() {
Block<T>* temp;
while (block != 0) {
temp = block;
block = block->next;
delete temp;
}
}
//获取迭代器
Iterator getIerator() {
return Iterator(this);
}
//当前元素数量
int getLength() {
return length;
}
//设置扩展步长
void setBlockSize(int size) {
blockSize = size;
}
//清空链表
void clear() {
while (true) {
if (length == 0)
return;
deallocate(used_tail);
}
}
//添加元素到链尾
void append(T const& item) {
Node<T>* temp = allocate();
temp->data = item;
used_tail->next = temp;
temp->pre = used_tail;
used_tail = temp;
used_tail->next = empty_head;
}
//弹出链尾元素
void pop() {
deallocate(used_tail);
}
//测试用
void print() {
using namespace std;
Node<T>* cur = pool[0].next;
while (cur != empty_tail) {
cout << cur->data << endl;
cur = cur->next;
}
}
private:
//分配节点
Node<T>* allocate() {
if (empty_head == empty_tail)
extend();
Node<T>* temp = empty_head;
empty_head = empty_head->next;
used_tail->next = empty_head;
length++;
return temp;
}
//回收节点
void deallocate(Node<T>* item) {
if (item == &pool[0])
return;
if (item == used_tail) {
item->next = empty_head;
empty_head->pre = item;
empty_head = empty_head->pre;
used_tail = used_tail->pre;
used_tail->next = empty_head;
length--;
return;
}
item->pre->next = item->next;
item->next->pre = item->pre;
item->next = empty_head;
empty_head->pre = item;
empty_head = item;
length--;
return;
}
//扩展内存池
void extend() {
Block<T>* newBlock = new Block<T > (blockSize);
block->next = newBlock;
Node<T>* newPool = newBlock->pool;
empty_tail->next = &(newPool[0]);
newPool[0].pre = empty_head;
empty_tail = &(newPool[blockSize - 1]);
}
private:
int length;
int blockSize;
Block<T>* block;
Node<T>* pool;
Node<T>* used_tail;
Node<T>* empty_head;
Node<T>* empty_tail;
};
#endif
在win7+gcc+netbean下测试通过,我最关注的append,insert,remove操作性能稍好于stl::list,但实用性,安全性,稳定性比不上stl::list,只是因为stl::list不符合自己的使用习惯和为了在irrlicht中调试错误方便,所以自己实现一个,附测试代码:
#include <iostream>
#include <list>
#include <time.h>
#include <sys/timeb.h>
#include "irrChain.h"
using namespace std;
__int64 getSystemTime() {
timeb t;
ftime(&t);
return 1000 * t.time + t.millitm;
}
void func1() {
cout << "irr::Chain" << endl;
__int64 before = getSystemTime();
Chain<int> chain;
chain.setBlockSize(500);
for (int i = 0; i < 500; i++) {
chain.append(i);
}
Chain<int>::Iterator itr = chain.getIerator();
for (itr.first(); itr.isOver(); itr.next()) {
if (itr.get() % 2 == 0 && itr.get() != 0) {
itr.insert(0);
} else {
//cout << itr.get() << endl;
}
}
__int64 after = getSystemTime();
cout << "used time:" << after - before << endl;
cout << "length:" << chain.getLength() << endl;
return;
}
void func2() {
cout << "stl::list" << endl;
__int64 before = getSystemTime();
list<int> test;
for (int i = 0; i < 500; i++) {
test.push_back(i);
}
list<int>::iterator itr = test.begin();
for (; itr != test.end(); itr++) {
if (*itr % 2 == 0 && *itr != 0) {
test.insert(itr, 0);
} else {
//cout << *itr << endl;
}
}
__int64 after = getSystemTime();
cout << "used time:" << after - before << endl;
cout << "length:" << test.size() << endl;
}
int main(int argc, char** argv) {
cout << "insert vs insert" << endl;
func1();
func2();
return 0;
}