⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clist.cpp

📁 预产期的计算
💻 CPP
字号:
#ifndef SCK_CLIST_CPP
#define SCK_CLIST_CPP
/////////////////////////////////////////////////////////////////////////////
// CList.cpp   双向链表类标准C++的声明及实现
// CopyRight(C)   1996,2008   TCSY 公司   圣诞节新版
// Pentium Working Room   ShanChengKun   2003.12.24   更新
/////////////////////////////////////////////////////////////////////////////

#define EMPTY_NODE		0							// 空节点,Del()返回
#define START_NODE		1							// 首节点,Del()标志
#define MIDDLE_NODE		2							// 中节点,Del()返回
#define LAST_NODE		3							// 尾节点,Del()标志
template<class T> class CList;						// 前置声明的CList类

//-------------------------------------------------------------------------//

// 自定义的通用链表节点类,T为简单数据类型
template<class T>									// 链表节点指针
class CNode
{
	friend class CList<T>;							// 友元.CList类
	long   no;										// 此节点的序号
	T      data;									// 此节点的数据
	CNode<T> *prior;								// 前驱节点指针
	CNode<T> *next;									// 后继节点指针

public: // 不负责释放由前驱后继的节点指针所指向的内存

	CNode() {no = -1; prior = next = NULL;}			// 默认构造函数
	CNode(T& dat) {no = -1; data = dat; prior = next = NULL;}
	T GetData(void) {return data;}					// 获取节点数据
	void SetData(T& dat) {data = dat;}				// 设置节点数据
};

//-------------------------------------------------------------------------//

// 自定义的通用链表类模板,T为简单数据类型
template<class T>									// 数据双向搜索
class CList
{
	long sum;										// 所有节点总数
	CNode<T> *start;								// 首节点的指针
	CNode<T> *last;									// 尾节点的指针
	CNode<T> *curr;									// 当前位置指针

public: // 向链首走=向上(向前),向链尾走=向下(向后)

	long Sum(void) {return sum;}					// 所有节点总数
	void Rewind(int w) {curr = (w ? last : start);}	// 0链首,1链尾
	T&   operator()(void) {return curr->data;}		// 引用当前节点
	long GetNth(void) {return (curr ? curr->no : -1);}// 取当前序号
	T&   operator[](long nth) {Seek(nth - curr->no); return curr->data;}

	CNode<T> *GetCurrPtr(void) {return curr;}		// 获取当前指针
	bool SetCurrPtr(CNode<T> *ptr)
	{
		if(!curr || !ptr) return false;				// 设置当前指针
		curr = ptr; return true;
	}

	bool Prev(void)									// 移动到上一点
	{
		if(!curr || !curr->prior) return false;
		curr = curr->prior; return true;
	}
	bool Next(void)									// 移动到下一点
	{
		if(!curr || !curr->next) return false;
		curr = curr->next; return true;
	}

	CList() {sum = 0; start = last = curr = NULL;}	// 缺省构造函数
	CList(CList<T>& list);							// 拷贝构造函数
	CList(T& dat) {sum = 0; start = last = curr = NULL; Add(dat);}
	~CList() {Destroy();}							// 默认析构函数

	bool Add(T& dat);								// 尾追加为当前
	int  Del(int bSort = 0);						// 删当前指向下
	bool Ins(T& dat, int bType, int bSort = 0);		// 当前前后插入
	void SortNo(void);								// 上点号起重编
	bool Seek(long num);							// -首向、+尾向
	void Destroy(void) {Rewind(1); while(Del());}	// 释放链表节点

	CList<T>& operator = (CList<T>& list);			// 重置为一新链
	CList<T>& operator = (T& dat);					// 重置为单节点
	CList<T>& operator += (CList<T>& list);			// 尾部追加新链
	CList<T>& operator += (T& dat);					// 尾部追加节点

	// 链表相加操作函数、右加节点操作函数、左加节点操作函数
	friend CList<T> operator + (CList<T>& list1, CList<T>& list2);
	friend CList<T> operator + (CList<T>& list, T& dat);
	friend CList<T> operator + (T& dat, CList<T>& list);
};

//-------------------------------------------------------------------------//

// 链表类的复制拷贝构造函数(此函数必须准确无误)
template<class T>
CList<T>::CList(CList<T>& list)
{
	sum = 0; start = last = curr = NULL;			// 注意这很重要
	if(!list.Sum()) return;							// 不拷贝空链表
	list.Rewind(0);									// 返回到链首点
	do {if(!Add(list())) break;} while(list.Next());// 遍历整个链表
}

// 在尾部追加一个数据节点
template<class T>
bool CList<T>::Add(T& dat)
{
	CNode<T> *info = new CNode<T>(dat);				// 申请拷贝空间
	if(!info) return false;
	info->no = sum++;								// 置序号总数增
	if(last) {info->prior = last; last->next = info; last = curr = info;}
	else start = last = curr = info; return true;	// 尾加载新节点
}

// 删除(空0、首1、中2、尾3)节点,默认不重排序号
template<class T>
int CList<T>::Del(int bSort)
{
	if(!curr) return EMPTY_NODE;					// 当前为空链表
	int nStyle = MIDDLE_NODE;						// 默认中间删除
	CNode<T> *prior = curr->prior, *next = curr->next;
	if(prior) prior->next = next;
	else {start = next; nStyle = START_NODE;}		// 删除的是首点
	if(next) next->prior = prior;
	else {last = prior; nStyle = LAST_NODE;}		// 删除的是尾点
	delete curr; curr = (next ? next : prior);
	sum--; if(bSort) SortNo(); return nStyle;		// 返回删除类型
}

// 在当前节点(0前/后1)插入,当前指向新点。默认不重排序号
template<class T>
bool CList<T>::Ins(T& dat, int bType, int bSort)
{
	if(curr == NULL) return Add(dat);				// 空则尾部追加
	CNode<T> *info = new CNode<T>(dat);				// 申请新点空间
	if(!info) return false;
	if(bType != 0)									// 在当前点之后
	{
		CNode<T> *&next = curr->next;				// 引用当前后继
		info->prior = curr; info->next = next;
		if(next) next->prior = info; else last = info;
		curr = next = info;							// 分尾点和中点
	}
	else											// 在当前点之前
	{
		CNode<T> *&prior = curr->prior;				// 引用当前前驱
		info->prior = prior; info->next = curr;
		if(prior) prior->next = info; else start = info;
		curr = prior = info;						// 分首点和中点
	}
	sum++; if(bSort) SortNo(); return true;			// 增总数并返回
}

// 以当前首向一节点序号为基数,重新编号
template<class T>
void CList<T>::SortNo(void)
{
	if(!curr) return;								// 上点序号为基
	curr->no = curr->prior ? curr->prior->no + 1 : 0;
	CNode<T> *info = curr;							// 从当前点开始
	while(info->next)
	{
		info->next->no = info->no + 1;				// 依次重新编号
		info = info->next;							// 不移当前指针
	}
}

// (负=首向、正=尾向)移动当前指针|num|次
template<class T>
bool CList<T>::Seek(long num)
{
	long count = 0, number = (num >0 ? num : -num);	// 绝对移动次数
	CNode<T> *info = curr;
	while(info && count < number)					// 是否已经足够
	{
		info = (num > 0 ? info->next : info->prior);// 尾向首向移动
		if(info) count++;
	}
	if(count != number) return false;				// 比较移动次数
	curr = info; return true;						// 当前指新位置
}

//-------------------------------------------------------------------------//

// 等号赋值函数=(置链为一新链)
template<class T>
CList<T>& CList<T>::operator = (CList<T>& list)
{
	if(&list == this) return *this;					// 不作自身拷贝
	Destroy(); if(!list.Sum()) return *this;		// 不拷贝空链表
	list.Rewind(0);									// 返回到首节点
	do {if(!Add(list())) break;} while(list.Next());// 遍历整个链表
	return *this;									// 返回实例引用
}

// 等号赋值函数=(置链为单节点),无法感知dat为本身节点
template<class T>
inline CList<T>& CList<T>::operator = (T& dat)
{
	Destroy(); Add(dat); return *this;				// 清空追加节点
}

// 加等号赋值函数+=(尾部追加新链)
template<class T>
CList<T>& CList<T>::operator += (CList<T>& list)
{
	if(&list == this || !list.Sum()) return *this;	// 非自身不拷空
	list.Rewind(0);									// 返回到首节点
	do {if(!Add(list())) break;} while(list.Next());// 遍历整个链表
	return *this;									// 返回实例引用
}

// 加等号赋值函数+=(尾部追加节点)
template<class T>
inline CList<T>& CList<T>::operator += (T& dat)
{
	Add(dat); return *this;							// 增加新单节点
}

//-------------------------------------------------------------------------//

// 链表相加操作函数
template<class T>
inline CList<T> operator + (CList<T>& list1, CList<T>& list2)
{
	CList temp(list1); temp += list2; return temp;	// 两个链表相加
}

// 右加节点操作函数
template<class T>
inline CList<T> operator + (CList<T>& list, T& dat)
{
	CList temp(list); temp.Add(dat); return temp;	// 尾部追加节点
}

// 左加节点操作函数
template<class T>
inline CList<T> operator + (T& dat, CList<T>& list)
{
	CList temp(dat); temp += list; return temp;		// 采用+=运算符
}

/////////////////////////////////////////////////////////////////////////////
#endif // #ifndef SCK_CLIST_CPP

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -