287 lines
6.4 KiB
C++
287 lines
6.4 KiB
C++
#ifndef _List_H_
|
|
#define _List_H_
|
|
|
|
#include "Sys.h"
|
|
|
|
// 数组长度
|
|
#define ArrayLength(arr) sizeof(arr)/sizeof(arr[0])
|
|
// 从数组创建列表
|
|
#define MakeList(T, arr) List<T>(&arr[0], sizeof(arr)/sizeof(arr[0]))
|
|
|
|
// 定长数组模版
|
|
template<typename T, int array_size>
|
|
struct array
|
|
{
|
|
T Arr[array_size];
|
|
|
|
int Count() { return array_size; }
|
|
|
|
//List<T> operator=(array arr) { return List<T>(arr.Arr, array_size); }
|
|
};
|
|
|
|
// 变长列表模版
|
|
template<typename T>
|
|
class List
|
|
{
|
|
public:
|
|
List() { _count = _total = 0; }
|
|
List(int size = 4)
|
|
{
|
|
_count = 0;
|
|
_total = size;
|
|
arr = new T[size];
|
|
}
|
|
List(T* items, uint count)
|
|
{
|
|
arr = new T[count];
|
|
|
|
_count = 0;
|
|
_total = count;
|
|
for(int i=0; i<count; i++)
|
|
{
|
|
arr[_count++] = *items++;
|
|
}
|
|
}
|
|
|
|
~List() { if(arr) delete[] arr; arr = NULL; }
|
|
|
|
void Add(T item)
|
|
{
|
|
// 检查大小
|
|
CheckSize();
|
|
|
|
arr[_count++] = item;
|
|
}
|
|
|
|
void Add(T* items, int count)
|
|
{
|
|
int size = _count + count;
|
|
if(size >= _total) ChangeSize(size * 2);
|
|
|
|
for(int i=0; i<count; i++)
|
|
{
|
|
arr[_count++] = *items++;
|
|
}
|
|
}
|
|
|
|
T* ToArray()
|
|
{
|
|
// 如果刚好完整则直接返回,否则重新调整空间
|
|
if(_count != _total)
|
|
{
|
|
T* arr2 = new T[_count];
|
|
memcpy(arr, arr2, _count);
|
|
delete[] arr;
|
|
arr = arr2;
|
|
}
|
|
return arr;
|
|
}
|
|
int Count() { return _count; }
|
|
|
|
// 重载索引运算符[],让它可以像数组一样使用下标索引。内部不检查下标越界,外部好自为之
|
|
T operator[](int i) { return arr[i]; }
|
|
T* operator=(List list) { return list.ToArray(); }
|
|
|
|
private:
|
|
T* arr;
|
|
uint _count;
|
|
uint _total;
|
|
|
|
void ChangeSize(int newSize)
|
|
{
|
|
if(_total == newSize) return;
|
|
|
|
T* arr2 = new T[newSize];
|
|
if(arr)
|
|
{
|
|
// 如果新数组较小,则直接复制;如果新数组较大,则先复制,再清空余下部分
|
|
if(newSize < _total)
|
|
memcpy(arr, arr2, newSize);
|
|
else
|
|
{
|
|
memcpy(arr, arr2, _total);
|
|
memset(arr2 + _total, newSize - _total);
|
|
}
|
|
delete[] arr;
|
|
}
|
|
arr = arr2;
|
|
}
|
|
|
|
void CheckSize()
|
|
{
|
|
// 如果数组空间已用完,则两倍扩容
|
|
if(_count >= _total) ChangeSize(_count * 2);
|
|
}
|
|
};
|
|
/*
|
|
// 双向链表
|
|
template <class T> class DblLinkedList;
|
|
|
|
// 双向链表节点
|
|
template <class T> class DblLinkedNode
|
|
{
|
|
T* _nextNode;
|
|
T* _prevNode;
|
|
|
|
// 友元类。允许链表类控制本类私有成员
|
|
friend class DblLinkedList<T>;
|
|
|
|
public:
|
|
void Initialize()
|
|
{
|
|
_nextNode = NULL;
|
|
_prevNode = NULL;
|
|
}
|
|
|
|
T* Next() const { return _nextNode; }
|
|
T* Prev() const { return _prevNode; }
|
|
|
|
void SetNext( T* next ) { _nextNode = next; }
|
|
void SetPrev( T* prev ) { _prevNode = prev; }
|
|
// 是否有下一个节点链接
|
|
bool IsLinked() const { return _nextNode != NULL; }
|
|
|
|
// 从链表中删除。需要修改前后节点的指针指向,但当前链表仍然指向之前的前后节点
|
|
void RemoveFromList()
|
|
{
|
|
T* next = _nextNode;
|
|
T* prev = _prevNode;
|
|
|
|
if(prev) prev->_nextNode = next;
|
|
if(next) next->_prevNode = prev;
|
|
}
|
|
|
|
// 完全脱离链表。不再指向其它节点
|
|
void Unlink()
|
|
{
|
|
T* next = _nextNode;
|
|
T* prev = _prevNode;
|
|
|
|
if(prev) prev->_nextNode = next;
|
|
if(next) next->_prevNode = prev;
|
|
|
|
_nextNode = NULL;
|
|
_prevNode = NULL;
|
|
}
|
|
};
|
|
|
|
// 双向链表
|
|
template <class T> class DblLinkedList
|
|
{
|
|
T* _first;
|
|
T* _last;
|
|
|
|
public:
|
|
void Initialize()
|
|
{
|
|
_first = Tail();
|
|
_last = Head();
|
|
}
|
|
|
|
// 计算链表节点数
|
|
int Count()
|
|
{
|
|
T* ptr;
|
|
T* ptrNext;
|
|
int num = 0;
|
|
|
|
for(ptr = FirstNode(); (ptrNext = ptr->Next()) != NULL; ptr = ptrNext)
|
|
{
|
|
num++;
|
|
}
|
|
|
|
return num;
|
|
}
|
|
|
|
T* FirstNode() const { return _first ; }
|
|
T* LastNode () const { return _last ; }
|
|
bool IsEmpty () const { return _first == Tail(); }
|
|
|
|
T* FirstValidNode() const { T* res = _first; return res->Next() ? res : NULL; }
|
|
T* LastValidNode () const { T* res = _last ; return res->Prev() ? res : NULL; }
|
|
|
|
T* Head() const { return (T*)((uint)&_first - offsetof(T, _nextNode)); }
|
|
T* Tail() const { return (T*)((uint)&_last - offsetof(T, _prevNode)); }
|
|
|
|
private:
|
|
|
|
// 在两个节点之间插入新节点
|
|
void Insert( T* prev, T* next, T* node )
|
|
{
|
|
node->_nextNode = next;
|
|
node->_prevNode = prev;
|
|
|
|
next->_prevNode = node;
|
|
prev->_nextNode = node;
|
|
}
|
|
|
|
public:
|
|
#if defined(_DEBUG)
|
|
BOOL Exists( T* searchNode )
|
|
{
|
|
T* node = FirstValidNode();
|
|
while( node != NULL && node != searchNode )
|
|
{
|
|
if (node == node->Next())
|
|
{
|
|
ASSERT(FALSE);
|
|
}
|
|
node = node->Next();
|
|
}
|
|
return (node == NULL? FALSE: TRUE);
|
|
}
|
|
#endif
|
|
|
|
void InsertBeforeNode( T* node, T* nodeNew )
|
|
{
|
|
if(node && nodeNew && node != nodeNew)
|
|
{
|
|
nodeNew->RemoveFromList();
|
|
|
|
Insert( node->Prev(), node, nodeNew );
|
|
}
|
|
}
|
|
|
|
void InsertAfterNode( T* node, T* nodeNew )
|
|
{
|
|
if(node && nodeNew && node != nodeNew)
|
|
{
|
|
nodeNew->RemoveFromList();
|
|
|
|
Insert( node, node->Next(), nodeNew );
|
|
}
|
|
}
|
|
|
|
void LinkAtFront( T* node )
|
|
{
|
|
InsertAfterNode( Head(), node );
|
|
}
|
|
|
|
void LinkAtBack( T* node )
|
|
{
|
|
InsertBeforeNode( Tail(), node );
|
|
}
|
|
|
|
// 释放第一个有效节点
|
|
T* ExtractFirstNode()
|
|
{
|
|
T* node = FirstValidNode();
|
|
|
|
if(node) node->Unlink();
|
|
|
|
return node;
|
|
}
|
|
|
|
// 释放最后一个有效节点
|
|
T* ExtractLastNode()
|
|
{
|
|
T* node = LastValidNode();
|
|
|
|
if(node) node->Unlink();
|
|
|
|
return node;
|
|
}
|
|
};
|
|
*/
|
|
#endif //_List_H_
|