#include<iostream>
#include<cassert>
using namespace std;
typedef int DataType;
struct Node
{
DataType data;
struct Node * next, * prior;
};
//typedef (int *)visit();
typedef Node * Node_point;
template<class DataType>
class CListLink
{
public:
CListLink();
~CListLink();
bool ListEmpty();
//若L为空表,则返回TRUE,否则FALSE
long ListLength();
//返回L中元素个数。
bool PriorElem(const DataType & cur_e, Node_point & pre_e);
//若cur_e是L的元素,但不是第一个,则用pre_e 返回它的前驱,否则操作失败,pre_e无定义
bool NextElem(const DataType & cur_e, Node_point & next_e );
//操作结果:若cur_e是L的元素,但不是最后一个,则用next_e返回它的后继,否则操作失败,next_e无定义。
bool GetElem(const long & i, DataType & e );
//初始条件:线性表L已存在,且 1≤i≤LengthList(L)
//操作结果:用 e 返回L中第 i 个元素的值。
bool LocateElem(Node_point & ret, const DataType & e,
bool (* compare)(const DataType &, const DataType &));
//返回L中第1个与e满足关系compare( )的元素的位序。若这样的元素不存在,则返回值为0
bool ListTraverse(void (* visit)(DataType &));//visit
//依次对L的每个元素调用函数visit( )。一旦visit( )失败,则操作失败
bool ClearList();
//将L重置为空表。
bool PutElem(const long & i, const DataType & e);
//初始条件:线性表 L 已存在,且 1≤i≤LengthList(L)。
//操作结果:把e值赋到L中第i个元素。
bool ListInsert(const long & i, const DataType & e);
//初始条件:线性表L已存在,且 1≤i≤LengthList(L)+1
//操作结果:在L的第i个元素之前插入新的元素e,L的长度增1。
bool ListDelete(const long & i, DataType & e);
//初始条件:线性表L已存在且非空,且1≤i≤LengthList(L)
//操作结果:删除L的第i个元素,并用e返回其值,L的长度减1。
bool ListInsert_Back(const DataType & e);
//操作结果:在L的最后面插入元素,L的长度增1。
protected:
Node_point List_head;
long length;
//newNode = new Node
//assert(newNode != null);
};
#include "CListLink.h"
//CListLink类定义
inline CListLink<DataType>::CListLink()
{
List_head = NULL;
length = 0;
}//CListLink
inline bool CListLink<DataType>::ClearList()
{
Node_point p = List_head;
while( length && p )
{
List_head = List_head->next;
delete p;
p = List_head;
length--;
}
if (!length)
{
List_head = NULL;
return true;
}
return false;
}//CleatList
inline CListLink<DataType>::~CListLink()
{
ClearList();
List_head = NULL;
}
inline bool CListLink<DataType>::ListEmpty()
{
return length > 0 ? false : true;
}//ListEmpty
inline long CListLink<DataType>::ListLength()
{
return length;
}//ListLength
inline bool CListLink<DataType>::PriorElem(const DataType & cur_e, Node_point & pre_e)
{
Node_point cur = List_head;
long len = length;
while (cur && len--)
{
if (cur->data == cur_e)
{
pre_e = cur->prior;
return true;
}
cur = cur->next;
}
return false;
}//PriorElem
inline bool CListLink<DataType>::NextElem(const DataType & cur_e, Node_point & next_e )
{
Node_point cur = List_head;
long len = length;
while (cur && len--)
{
if (cur->data == cur_e)
{
next_e = cur->next;
return true;
}
cur = cur->next;
}
return false;
}//NextElem
inline bool CListLink<DataType>::GetElem(const long & i, DataType & e )
{
if (i <= 0 || i > length || !List_head)
return false;
Node_point p = List_head;
for (int j = 1; j < i; j++)
p = p->next;
e = p->data;
return true;
}//GetElem
inline bool CListLink<DataType>::PutElem(const long & i, const DataType & e)
{
if (i <= 0 || i > length || !List_head)
return false;
Node_point p = List_head;
for (int j = 1; j < i; j++)
p = p->next;
p->data = e;
return true;
}//PutElem
bool CListLink<DataType>::ListInsert(const long & i, const DataType & e)
{
if (i < 1 || i > length || !List_head)
return false;
Node_point p = List_head;
Node_point newNode = new Node;
assert(newNode != NULL);
newNode->next = newNode->prior = NULL;
newNode->data = e;
for (int j = 1; j < i; j++)
p = p->next;
newNode->prior = p->prior;
p->prior->next = newNode;
newNode->next = p;
p->prior = newNode;
length++;
return true;
}//ListInsert
bool CListLink<DataType>::ListDelete(const long & i, DataType & e)
{
if (length == 0 || i > length || i < 1)
return false;
Node_point p = List_head;
for (int j = 1; j < i; j++)
p = p->next;
e = p->data;
length--;
if (length == 0)//空表
{
delete p;
List_head = NULL;
return true;
}
if (p == List_head)
List_head = p->next;
p->prior->next = p->next;
p->next->prior = p->prior;
delete p;
return true;
}//ListDelete
bool CListLink<DataType>::ListInsert_Back(const DataType & e)
{
Node_point newNode = new Node;
assert(newNode != NULL);
newNode->next = newNode->prior = newNode;
newNode->data = e;
if (List_head == NULL)
{
List_head = newNode;
}
else
{
newNode->prior = List_head->prior;
List_head->prior->next = newNode;
newNode->next = List_head;
List_head->prior = newNode;
}
length++;
return true;
}//ListInsert_Back
bool CListLink<DataType>::LocateElem(Node_point & ret, const DataType & e,
bool (* compare)(const DataType &, const DataType &))
{
if (List_head == NULL)
return false;
Node_point cur = List_head;
long len = length;
while (cur && len--)
{
if (compare(cur->data, e))
{
ret = cur;
return true;
}
cur = cur->next;
}
return false;
}
bool CListLink<DataType>::ListTraverse(void (* visit)(DataType &))
{
if (List_head == NULL)
return false;
Node_point cur = List_head;
long len = length;
while (cur && len--)
{
visit(cur->data);
cur = cur->next;
}
return true;
}