双向链表C++,C#,Java版,这些程序大多已经过测试,一直在用。

先C++版吧,我最先用的是C#,后来是Java,后来改用C++版的,因为现在一直在用C++,单链

表一直没写上去,因为我很少用,用的是双链表。

执行代码例子1:

int main()
{
     
    _DList<_string>  sl = { "123","a1","b4","1998","wc" };

    _pcn(sl);

    sl.Sort_Selection();

    _pcn(sl);

}

输出:

执行代码例子2:


void test()
{
    _DList<_string>  sl = { "123","a1","b4","1998","wc" };

    std::cout << "使用内存:" << _Memory::mem_used() << "\n";

    sl.Sort_Selection();

    std::cout << "使用内存:" << _Memory::mem_used() << "\n";
}

int main()
{
    std::cout << "使用内存:" << _Memory::mem_used() << "\n";
     

    test();

    std::cout << "使用内存:" << _Memory::mem_used() << "\n";
}

1. C++版

_List.h

/*******************************************************************************************
文件名			: list.h作者				: 李锋功能				: 链表创建时间			: 2016年07月31日最后一次修改时间	:  2021年10月23日/// 链表是一种用来存储数据集合的数据结构。链表具有如下属性
///(1)元素通过指针依次相连
///(2)最后一个元素的指针为空(null)。
///(3)在程序的执行过程中,链表的长度可以自由伸缩。
///(4)链表的长度可以要求的任意长度(除非系统内存耗尽)。
///(5)它不会浪费内存空间(但会需要额外的内存空间存储指针)。记住: Virtual C++  Bug:   模板继承用到父类成员访问时,要用 this->********************************************************************************************/
#ifndef  __LIST_H_
#define  __LIST_H_#include "_Macro.h"
#include "_Memory.h"
#include "_ByteArray.h" 
#include "_Pair.h"_LF_BEGIN_/// <summary>
/// 排序顺序
/// </summary>
enum class _SortOrder
{s_Minmax = 0,   //从小到大   s_Maxmin = 1,   //从大到小s_null = 2       //无排序顺序
};/// <summary>
/// 单链表节点
/// </summary>
/// <typeparam name="T"></typeparam>
/// 创建时间	 2021年10月23日   最后一次修改时间	:  2021年10月23日
template<class T>
class _SListNode
{public:/// <summary>/// 节点数据/// </summary>T Data;/// <summary>/// 下一个节点/// </summary>_SListNode<T>* Next;/// <summary>/// 构造函数/// </summary>/// <param name="aData"></param>_SListNode(T aData){Data = aData;}};/// <summary>
///  C#语句:public class _DListNode<T>
/// </summary>
/// <typeparam name="T">默认数据</typeparam>
template<class T>
class _DListNode   
{
public:/// <summary>/// 节点数据/// </summary>T Data;/// <summary>/// 前一个节点/// </summary>_DListNode<T>* Prev;/// <summary>/// 下一个节点/// </summary>_DListNode<T>* Next;/// <summary>/// 构造函数/// </summary>/// <param name="aData">默认数据</param>_DListNode(const T& aData){Data = aData;Prev = null;Next = null;}_DListNode(){Prev = null;Next = null;Data = T();}
};/// <summary>
/// 单链表:
///     通常我们说的链表指的是单链表(singly linked list)。单链表包括一组结点,每个结
/// 点有一个 next 指针域,用来存储指向(逻辑上)下一个元素对应结点的指针。最后一个结点的
/// next指针域的值为null,这预示着已经到达链表的尾部。
/// 
/// </summary>
/// <typeparam name="T"></typeparam>
template<class T>
class _SList  : public _Object
{
private:/// <summary>/// 第一个结点/// </summary>_SListNode<T>* _First;/// <summary>/// 结点数/// </summary>int _Count;public:inline const int& Count() { return _Count; }inline const _SListNode<T>* First() { return _First; }};//------------------------------------------LDIterator
//参考网址:  https://blog.csdn.net/qq_28398301/article/details/106321525          C++用for遍历自定义类/// <summary>
/// 
/// </summary>
/// <typeparam name="T"></typeparam>
template<class T>
class _DListNodeIterator
{
private:_DListNode<T>* _pNode;
public:/// <summary>/// 构造函数,传值迭代器管理的值/// </summary>/// <param name="pNode"></param>inline _DListNodeIterator(_DListNode<T>* pNode) { _pNode = pNode; }/// <summary>/// 比较实现/// </summary>/// <param name="that"></param>/// <returns></returns>bool operator != (const _DListNodeIterator& that) { return _pNode != that._pNode; }/// <summary>/// 自增实现/// </summary>/// <returns></returns>inline _DListNodeIterator& operator ++ () { _pNode = _pNode->Next;   return *this; }/// <summary>/// 解引用,取值/// </summary>/// <typeparam name="T"></typeparam>T& operator * () { return _pNode->Data; }//LDIterator(const LDIterator&) = delete;//LDIterator& operator=(const LDIterator&) = delete;//~LDIterator() = default;
};/// <summary>
/// 双向链表,  数据 T 要求能够比较大小,否则编译会出错。
/// </summary>
/// <typeparam name="T"></typeparam>
template<class T>
class _DList : public _Object
{
protected:_DListNode<T>*  _First;	        //第一个节点_DListNode<T>*   _Last;		    //最后一个节点int             _Count;			//节点个数int             _MaxBuffer;     //双链表最大可以存储的元素个数_SortOrder      _so;        //排序顺序protected:/// <summary>/// 初台化数据/// </summary>/// <returns></returns>inline void InitData() {_Count = 0; _First = null; _Last = null; _MaxBuffer = 100000;_so = _SortOrder::s_null;}public: //---------------------------------------------------------------------------属性__declspec(property(get = GetSortOrder, put = SetSortOrder) )  _SortOrder SortOrder;const _SortOrder& GetSortOrder() const { return _so; }virtual void SetSortOrder(const _SortOrder so) { _so = so; }__declspec(property(get = GetCount)) const int Count;inline int GetCount() const { return _Count; }public://------------------------------------------------------------构造与析构/// <summary>/// 默认构造函数/// </summary>/// <returns></returns>inline _DList(){InitData();}inline _DList(const _DList& dl){//_cout << _t("inline _DList<T>::_DList(const _DList& dl)\n");InitData();_DListNode<T>* dn = dl.First();while (dn != null){Add(dn->Data);dn = dn->Next;}}inline _DList(const T& item) {InitData();Add(item);}/// <summary>/// 列表初始化  dList<int> idl = {1,2,3,4};/// </summary>/// <typeparam name="T"></typeparam>/// <param name="tList"></param>inline _DList(std::initializer_list<T> tList){InitData();for (T t : tList) { Add(t); }}/// <summary>/// 析构函数/// </summary>inline virtual ~_DList(){//_cout << _t("inline _DList<T>::~_DList()\n");ClearData();}//------------------------------------------------------------属性/// <summary>/// 双链表最大可以存储的元素个数/// </summary>int MaxBuffer()const { return _MaxBuffer; }/// <summary>///设定双链表最大可以存储的元素个数/// </summary>/// <param name="nCaptionty"></param>inline void MaxBuffer(int nCaptionty) { _MaxBuffer = nCaptionty; }inline int CSharp_Count() const { return _Count; }inline _DListNode<T>* First()const { return _First; }inline _DListNode<T>* Last()const { return _Last; }inline _DListNodeIterator<T> begin()const { return _DListNodeIterator<T>(_First); }/// <summary>/// /// </summary>/// <returns></returns>inline _DListNodeIterator<T> end()const{//迭代器使用的语句//for (_DListNodeIterator<int> f = dl.begin(); f != dl.end(); f++) {       }return _DListNodeIterator<T>(null);}//-----------------------------------------------------------运算符重载/// <summary>/// 重载的下标操作符 []/// </summary>T& operator[](const int& nIndex) const {  return IndexOfNode(nIndex)->Data; }/// <summary>/// 重载的下标操作符 =/// </summary>/// 创建时间: ????-??-??      最后一次修改时间:2024-04-19     inline _DList<T>& operator = (const _DList<T>& other){if (this != &other){ClearData();Add(other);              }return *this;}/// <summary>/// 类型转换/// </summary>inline operator _string() const{ return ToString(); }/// <summary>/// 类型转换/// </summary>inline operator _stdstr() const { return ToString().Data; }//---------------------------------------------------------虚函数重写/// <summary>/// 是否存在 item/// </summary>inline virtual bool Contains(const T& item){ return BinarySearch(item) != -1; }/// <summary>/// 交换两个节点的数据/// </summary>/// <typeparam name="T"></typeparam>/// <param name="iIndex1"></param>/// <param name="iIndex2"></param>/// <returns></returns>inline bool SwapNodeData(const int& iIndex1, const int& iIndex2){_DListNode<T>* pNode1, * pNode2;pNode1 = IndexOfNode(iIndex1);pNode2 = IndexOfNode(iIndex2);if (!(pNode1 != null && pNode2 != null)){return false;}T ptmp = pNode1->Data;pNode1->Data = pNode2->Data;pNode2->Data = ptmp;return true;}/// <summary>/// 选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是:第一次从待排序的数据元素中选出最小/// 或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序/// 的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。/// </summary>/// <typeparam name="T"></typeparam>/// <param name="sortord"></param>/// 创建时间: ???-??-??      最后一次修改时间:???-??-??    已测试inline virtual void Sort_Selection(const _SortOrder& sortord = _SortOrder::s_Minmax){if (_Count == 0 || _Count == 1) return;_DListNode<T>* min = _First, * tmp = _First->Next;if (sortord == _SortOrder::s_Minmax) //从小到大{while (min->Next != null){while (tmp != null){if (tmp->Data < min->Data)  //交换数据{T pt = tmp->Data;tmp->Data = min->Data;min->Data = pt;}tmp = tmp->Next;}min = min->Next;tmp = min->Next;}}else{while (min->Next != null){while (tmp != null){if (tmp->Data > min->Data){T pt = tmp->Data;tmp->Data = min->Data;min->Data = pt;}tmp = tmp->Next;}min = min->Next;tmp = min->Next;}}this->_so = sortord;  //已排序}/// <summary>/// 返回索引的节点/// </summary>inline virtual _DListNode<T>* IndexOfNode(const int& iPos)const{if (iPos < 0 || iPos >= _Count) //错误索引:{return NULL;}unsigned int nindex = 0;if (iPos > _Count / 2){_DListNode<T>* pNode = _Last;while (pNode != null){if (nindex++ == _Count - iPos - 1) { return pNode; }pNode = pNode->Prev;}}else{_DListNode<T>* pNode = _First;while (pNode != null){if (nindex++ == iPos){return pNode;}pNode = pNode->Next;}}return null;}/// <summary>/// 把索引为nIndex的节点移到最后/// </summary>/// <typeparam name="T"></typeparam>/// <param name="iIndex"></param>/// <returns></returns>inline virtual bool MoveLast(const int& iIndex){_DListNode<T>* pNode = IndexOfNode(iIndex);if (pNode != null){if (pNode == _Last)return true;if (pNode == _First) //此时最少两个节点{_First = _First->Next;_First->Prev = null;_Last->Next = pNode;pNode->Prev = _Last;_Last = pNode;}else{pNode->Prev->Next = pNode->Next;pNode->Next->Prev = pNode->Prev;_Last->Next = pNode;pNode->Prev = _Last;_Last = pNode;}return true;}return false;}/// <summary>/// 把节点移到最后/// </summary>/// 创建时间: 2022-02-18      最后一次修改时间:2022-02-18inline virtual bool MoveLast(_DListNode<T>* dnCurrent){if (dnCurrent == null) return false;this->_so = _SortOrder::s_null;if (_Count == 0){return false;}else if (_Count == 1){return true;}else if (_Count == 2){if (dnCurrent == _First)  //交换_First 与 _Last 数据{T tmp = _First->Data;_First->Data = _Last->Data;_Last->Data = tmp;}return true;}else{if (dnCurrent == _First){_First = _First->Next;_First->Prev = null;_Last->Next = dnCurrent;dnCurrent->Next = null;dnCurrent->Prev = _Last;_Last = dnCurrent;}else if (dnCurrent != _Last){dnCurrent->Prev->Next = dnCurrent->Next;dnCurrent->Next->Prev = dnCurrent->Prev;_Last->Next = dnCurrent;dnCurrent->Next = null;dnCurrent->Prev = _Last;_Last = dnCurrent;}return true;}}/// <summary>/// 把索引为nIndex的节点移到最前/// </summary>/// <param name="iIndex"></param>inline virtual bool MoveFirst(const int& iIndex){_DListNode<T>* pNode = IndexOfNode(iIndex);if (pNode != null){if (pNode == _First)return true;if (pNode == _Last)  //此时最少两个节点{_Last->Prev->Next = null;_Last = _Last->Prev;pNode->Prev = null;pNode->Next = _First;_First->Prev = pNode;_First = pNode;}else{pNode->Prev->Next = pNode->Next;pNode->Next->Prev = pNode->Prev;pNode->Next = _First;_First->Prev = pNode;pNode->Prev = null;_First = pNode;}return true;}return false;}/// <summary>/// 将指定集合的元素添加到末尾/// </summary>/// <typeparam name="T"></typeparam>/// <param name="item"></param>/// <returns></returns>inline virtual bool Add(const T& item){if (_Count == 0){//_First = new _DListNode<T>(item);_First = _Memory::New< _DListNode<T> >(1);_First->Data = item;_First->Next = null;_First->Prev = null;_Last = _First;}else{_DListNode<T>* pNew = _Memory::New< _DListNode<T> >(1);pNew->Data = item;pNew->Next = null;pNew->Prev = _Last;_Last->Next = pNew;_Last = pNew;}++_Count;this->_so = _SortOrder::s_null;   //要重新排序return true;}/// <summary>/// 添加一个链表/// </summary>inline void  Add(const _DList<T>& dList){assert(&dList != null);_DListNode<T>* pNode = dList._First;while (pNode != null){Add(pNode->Data);pNode = pNode->Next;}}
protected:/// <summary>/// 在结点pListItem前面插入一个结点,成功,返回新的结点,否则返回null/// </summary>/// <typeparam name="T"></typeparam>/// <param name="pListItem"></param>/// <param name="rData"></param>/// <returns></returns>inline virtual _DListNode<T>* InserNodeFront(_DListNode<T>* pListItem, const T& rData){assert(pListItem != null);_DListNode<T>* pNode = _Memory::New<_DListNode<T>>(1);pNode->Data = rData;//pNode            pNode->Next = pListItem;pNode->Prev = pListItem->Prev;//--pListItem->Previf (pListItem->Prev != null){pListItem->Prev->Next = pNode;}else{_First = pNode;}//pListItempListItem->Prev = pNode;++_Count;return pNode;}/// <summary>/// 在结点pListItem后面插入一个结点,成功,返回新的结点,否则返回0;/// </summary>/// <typeparam name="T"></typeparam>/// <param name="pListItem"></param>/// <param name="rData"></param>/// <returns></returns>inline virtual _DListNode<T>* InserNodeBack(_DListNode<T>* pListItem, const T& rData){if (pListItem == null) return null;_DListNode<T>* pNode = _Memory::New<_DListNode<T>>(1);pNode->Data = rData;//pNodepNode->Prev = pListItem;pNode->Next = pListItem->Next;//pListItem->Nextif (pListItem->Next != null){pListItem->Next->Prev = pNode;}else{_Last = pNode;}//--pListItempListItem->Next = pNode;++_Count;return pNode;}//------------------------------------------------------------操作         
public:/// <summary>/// 如果已排好序,它会按二分法查找,否则它会普通查找。/// </summary>/// <param name="item"></param>/// <returns></returns>/// 创建时间: ????-??-??      最后一次修改时间:????_??_??       已测试inline int BinarySearch(const T& item)const {switch (this->_so){case _SortOrder::s_Maxmin:{if (_Count == 0){return -1;}if (_Count == 1){//return (_First.Data as IComparable).CompareTo(item) == 0 ? 0 : -1;  //C#return _First->Data == item ? 0 : -1;}if (_Count == 2){//if ((_First.Data as IComparable).CompareTo(item) == 0) return 0;//if ((_First.Next.Data as IComparable).CompareTo(item) == 0) return 1;if (_First->Data == item) return 0;if (_First->Next->Data == item) return 1;return -1;}int nPos = (int)_Count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = (int)_Count - 1;  //右边远素_DListNode<T>* pNode;while (nRight >= 0 && nLeft >= 0){pNode = IndexOfNode(nPos);//int iCom = (item as IComparable).CompareTo(ld.Data);if (item > pNode->Data){if (nRight == nLeft || nPos == nLeft){return -1;}nRight = nPos - 1;}else if (item < pNode->Data){if (nRight == nLeft || nPos == nRight){return -1;}nLeft = nPos + 1;}else{return nPos;}nPos = nLeft + (nRight - nLeft + 1) / 2;}break;}case _SortOrder::s_Minmax:{if (_Count == 0){return -1;}if (_Count == 1){//return (_First.Data as IComparable).CompareTo(item) == 0 ? 0 : -1;return _First->Data == item ? 0 : -1;}if (_Count == 2){//if ((_First.Data as IComparable).CompareTo(item) == 0) return 0;//if ((_First.Next.Data as IComparable).CompareTo(item) == 0) return 1;if (_First->Data == item) return 0;if (_First->Next->Data == item) return 1;return -1;}int nPos = (int)_Count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = (int)_Count - 1;  //右边远素_DListNode<T>* pNode = null;while (nRight >= 0 && nLeft >= 0){pNode = IndexOfNode(nPos);//int iCom = (item as IComparable).CompareTo(ld.Data);if (item < pNode->Data){if (nRight == nLeft || nPos == nLeft){return -1;}nRight = nPos - 1;}else if (item > pNode->Data){if (nRight == nLeft || nPos == nRight){return -1;}nLeft = nPos + 1;}else{return nPos;}nPos = nLeft + (nRight - nLeft + 1) / 2;}break;}case _SortOrder::s_null:{_DListNode<T>* pNode = _First;int iCount = 0;while (pNode != null){if (pNode->Data == item){return iCount;}pNode = pNode->Next;++iCount;}break;}default:{return -1;}}return -1;}/// <summary>/// 清除节点,并释放内存/// </summary>/// <typeparam name="T"></typeparam>/// 创建时间: ????-??-??      最后一次修改时间:2022-12-24    (已测试)inline void ClearData() override { ClearMemory(); }/// <summary>/// 清除节点,并释放内存/// </summary>inline void ClearMemory() override{_Count = 0;_DListNode<T>* dn = _First;while (dn != null){if (dn->Prev != null)_Memory::Delete< _DListNode<T> >(dn->Prev, 1);dn = dn->Next;}if (_Last != null)_Memory::Delete< _DListNode<T> >(_Last, 1);_First = null;_Last = null;this->_so = _SortOrder::s_null;}/// <summary>/// 复制一个链表,清除原来链表的数据/// </summary>/// <typeparam name="T"></typeparam>/// <param name="ld"></param>inline void CopyFrom(const _DList<T>& ld){if (this != &ld){ClearData();_DListNode<T>* pNode = ld._First;while (pNode != null){Add(pNode->Data);pNode = pNode->Next;}}}/// <summary>/// 移除指定索引处的元素/// </summary>/// <typeparam name="T">类型</typeparam>/// <param name="iIndex">要移除的元素的从零开始的索引。</param>/// <returns>成功返回true,否则返回false</returns>/// 创建时间:????-??-?? 最后一次修改时间:2023-04-08inline bool RemoveAt(const int& iIndex){if (iIndex < 0 || iIndex >= _Count) return false;_DListNode<T>* pNode = _First;int iCount = 0;while (pNode != null){if (iCount == iIndex){if (pNode == _First){if (_First->Next == null)   //只有一个{ClearData();return true;}else{_First = _First->Next;_First->Prev = null;--_Count;_Memory::Delete<  _DListNode<T> >(pNode, 1);return true;}}else if (pNode == _Last){if (_Last->Prev == null){ClearData();return true;}else{ _Last = _Last->Prev;_Last->Next = null;--_Count;_Memory::Delete< _DListNode<T>>(pNode, 1);return true;}}else{pNode->Prev->Next = pNode->Next;pNode->Next->Prev = pNode->Prev;--_Count;_Memory::Delete< _DListNode<T>>(pNode, 1);return true;}}pNode = pNode->Next;++iCount;}return false;}/// <summary>/// 查找一项数据/// </summary>inline _DListNode<T>* FindNodeItem(const T& item)const{switch (this->_so){case _SortOrder::s_Maxmin:{if (_Count == 0){return null;}if (_Count == 1){//return (_First.Data as IComparable).CompareTo(item) == 0 ? _First : null;return _First->Data == item ? _First : null;}if (_Count == 2){//if ((_First.Data as IComparable).CompareTo(item) == 0) return _First;//if ((_First.Next.Data as IComparable).CompareTo(item) == 0) return _First.Next;if (_First->Data == item) return _First;if (_First->Next->Data == item) return _First->Next;return null;}int nPos = (int)(_Count / 2);   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = (int)(_Count - 1);  //右边远素_DListNode<T>* pNode = null;while (nRight >= 0 && nLeft >= 0){pNode = IndexOfNode(nPos);//int iCom = (item as IComparable).CompareTo(ld.Data);if (item > pNode->Data){if (nRight == nLeft || nPos == nLeft){return null;}nRight = nPos - 1;}else if (item < pNode->Data){if (nRight == nLeft || nPos == nRight){return null;}nLeft = nPos + 1;}else{return pNode;}nPos = nLeft + (nRight - nLeft + 1) / 2;}break;}case _SortOrder::s_Minmax:{if (_Count == 0){return null;}if (_Count == 1){//return (_First.Data as IComparable).CompareTo(item) == 0 ? _First : null;return _First->Data == item ? _First : null;}if (_Count == 2){//if ((_First.Data as IComparable).CompareTo(item) == 0) return _First;//if ((_First.Next.Data as IComparable).CompareTo(item) == 0) return _First.Next;if (_First->Data == item) return _First;if (_First->Next->Data == item) return _First->Next;return null;}int nPos = (int)(_Count / 2);   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = (int)(_Count - 1);  //右边远素_DListNode<T>* pNode = null;while (nRight >= 0 && nLeft >= 0){pNode = IndexOfNode(nPos);//int iCom = (item as IComparable).CompareTo(ld.Data);if (item < pNode->Data){if (nRight == nLeft || nPos == nLeft){return null;}nRight = nPos - 1;}else if (item > pNode->Data){if (nRight == nLeft || nPos == nRight){return null;}nLeft = nPos + 1;}else{return pNode;}nPos = nLeft + (nRight - nLeft + 1) / 2;}break;}case _SortOrder::s_null:{_DListNode<T>* pNode = _First;while (pNode != null){//总结:Equals比较的永远是变量的内容是否相同,而= =比较的则是引用地址是否相同(前提:此种类型内部没有对Equals 或= = 进行重写操作,//否则输出可能会有不同)。string 类型是个特例,因为他的内部对这两个都进行了重写。if (item == pNode->Data){return pNode;}/*if (pNode.Data.Equals(item)){return pNode;}*/pNode = pNode->Next;}break;}default:{return null;}}return null;}/// <summary>/// 删除链表中的数据/// </summary>/// <typeparam name="T"></typeparam>/// <param name="pData"></param>/// <returns></returns>inline bool RemoveItem(const T& pData){if (this->_so == _SortOrder::s_null){_DListNode<T>* pNode = _First;while (pNode != null){if (pNode->Data == pData)	//找到一项{if (pNode == _First)		//删除的是第一个节点{if (_First->Next != null){_First->Next->Prev = null;_First = _First->Next;}else{_First = null;_Last = null;}}else if (pNode == _Last)  //删除的是最后一个节点{if (_Last->Prev != null){_Last->Prev->Next = null;_Last = _Last->Prev;}else{_Last = null;_Last = null;}}else						//删除的是中间的一个节点{pNode->Next->Prev = pNode->Prev;pNode->Prev->Next = pNode->Next;}--_Count;return true;}pNode = pNode->Next;}return false;}else{return RemoveAt(BinarySearch(pData));}}/// <summary>/// 删除最后一个节点/// </summary>/// 创建时间:2020-09-12  最后一次修改时间: 2023-01-18inline bool DeleteLast(){auto pDelete = Last();if (_Count <= 0){return false;}else if (_Count == 1){_First = null;_Last = null;_Count = 0;}else if (_Count == 2){_Last = _First;_Last->Prev = null;_Last->Next = null;_First->Next = null;_First->Prev = null;--_Count;}else{_Last->Prev->Next = null;_Last = _Last->Prev;--_Count;}_Memory::Delete<_DListNode<T>>(pDelete, 1);return true;}/// <summary>/// 添加一个元素,并把它放在首位,其它元素后移,如果后面的元素删除,总无素个数不变,如果元素个数为零,则添加一个无素。/// </summary>/// <param name="Item"></param>/// <param name="bRemoveLast"></param>/// 创建时间: 2022-04-19      最后一次修改时间:2022-04-19inline void HistoryAdd(const T& Item, bool bRemoveLast){if (_Count == 0) {Add(Item);}else if (_Count == 1) {if (bRemoveLast) {_First->Data = Item;}else {//把无素放在最前_DListNode<T>* dnNew = _Memory::New<_DListNode<T>>(1);dnNew->Data = Item;_First->Prev = dnNew;dnNew->Next = _First;_First = dnNew;++_Count;}}else {if (bRemoveLast) {_DListNode<T>* dnDelete = _Last;//删除最后一个元素_Last = _Last->Prev;_Last->Next = null;_DListNode<T>* dnNew = _Memory::New<_DListNode<T>>(1);dnNew->Data = Item;_First->Prev = dnNew;dnNew->Next = _First;dnNew->Prev = null;_First = dnNew;_Memory::Delete< _DListNode<T>>(dnDelete, 1);}else {//把无素放在最前_DListNode<T>* dnNew = _Memory::New<_DListNode<T>>(1);dnNew->Data = Item;_First->Prev = dnNew;dnNew->Next = _First;dnNew->Prev = null;_First = dnNew;++_Count;}}}/// <summary>/// 出栈(先进后出),删除最后一个元素,/// </summary>/// 创建时间: 2022-04-19      最后一次修改时间:2023-04-06inline T StackPop(){assert(_Count > 0);T tResult = _Last->Data;this->RemoveAt(_Count - 1);return tResult;}//----------------------------------------------------------------------------------------------------Python List方法/// <summary>/// 将元素tItem添加到列表末尾。/// </summary>/// 创建时间: 2023-04-08      最后一次修改时间:2023-04-08inline void Python_append(const T& tItem){Add(tItem);}/// <summary>/// 在位置nIndex后面插入一个元素tItem/// </summary>inline void Python_insert(const int nIndex, const T& tItem){InserNodeBack(IndexOfNode(nIndex), tItem);}/// <summary>/// 在最前面插入一项/// </summary>/// <param name="tItem"></param>/// 创建时间: 2024-04-16      最后一次修改时间:2024-04-16inline void Inseart_front(const T& tItem){_DListNode<T>* pNode = _Memory::New<_DListNode<T>>(1);pNode->Data = tItem;if (_First != null){_First->Prev = pNode;pNode->Next = _First;pNode->Prev = null;_First = pNode;}else{ pNode->Next = null;pNode->Prev = null;_First = pNode;_Last = pNode;}++_Count;}/// <summary>/// 删除索引位置为nIndex的元素,并返回删除的元素值的拷贝,如果索引值nIndex = -1,则默认删除为最后一个元素。/// </summary>/// <param name="nIndex"></param>/// <returns></returns>/// 创建时间: 2023-04-08      最后一次修改时间:2023-04-09inline T Python_pop(const int nIndex = -1){if (nIndex == -1){         return StackPop();}else{ auto dn = this->IndexOfNode(nIndex);T tmp = T();if (dn != null){tmp = dn->Data;                  DeleteNode(dn);}return tmp;}         }/// <summary>/// 删除值为tItem的一项。/// 注意,方法remove()只删除第一个指定的值。如果要删除的值可能在列表中出现多次,/// 就需要使用循环来确保每个值都删除。/// </summary>inline bool Python_remove(const T& tItem){ int n = _Count;DeleteNode(FindNodeItem(tItem));return n == _Count;}protected:/// <summary>/// 删除链表中的节点/// </summary>/// <typeparam name="T"></typeparam>/// <param name="pListItem"></param>/// <returns></returns>//inline bool DeleteNode(const _DListNode<T>* pNodeDelete)//{//    if (_Count == 0 || pNodeDelete == null)//    {//        return false;//    }//    _DListNode<T>* pNode = _First.Next;//    while (pNode != null)//    {//        if (pNode == pNodeDelete)  //找到了//        {//            //pListItem->Prev//            if (pNodeDelete->Prev != null)//            {//                pNodeDelete->Prev->Next = pNodeDelete->Next;//            }//            else //删除的是第一个节点//            {//                _First = pNodeDelete.Next;//            }//            //pListItem->Next//            if (pNodeDelete->Next != null)//            {//                pNodeDelete->Next->Prev = pNodeDelete->Prev;//            }//            else //删除的是最后一个节点//            {//                _Last = pNodeDelete->Prev;//            }//            break;//        }//        pNode = pNode->Next;//    }//    if (pNode != null)//    {//        --_Count;//        _Memory::Delete< _DListNode<T> >(pNode,1);  //C#不用清除内存//        return true;//    }//    return false;//}/// <summary>/// 删除链表中的某一节点,注意,这个节点一定要是在链表中的。/// </summary>/// 创建时间: 2023-04-09      最后一次修改时间:2023-04-09inline void DeleteNode(_DListNode<T>* pNodeDelete){if (_Count == 0 || pNodeDelete == null) return;if (_Count == 1){ClearMemory();}else{if (pNodeDelete == _First) //删除的是第一个节点{_First = _First->Next;_First->Prev = null;}else if (pNodeDelete == _Last){_Last = _Last->Prev;_Last->Next = null;}else{pNodeDelete->Prev->Next = pNodeDelete->Next;pNodeDelete->Next->Prev = pNodeDelete->Prev;}--_Count;_Memory::Delete< _DListNode<T> >(pNodeDelete, 1);}}public://----------------------------------------------------------  C++inline void Push_back(const T& TypeObject) { Add(TypeObject); }public: //------------------------------------------------------------------重写/// <summary>/// 转换为字符串/// </summary>/// <returns></returns>/// 创建时间: 2023-05-16      最后一次修改时间:2024-01-14inline virtual  _string ToSplitString(const _string& sSplitString)  const override{//不可以这样: const _DList<_Object>* dp = (_DList<_Object> *)pList;//就算 T 类型数据是从 _Object中继承也不可以。_string sResult;sResult.Add(_t("{"));_string sp = sSplitString.Length == 0 ? _string(_t(",")) : sSplitString;//是否继承处_Objectif (std::is_base_of<_Object, T>::value){  _Object* po;if (_Count == 1){po = (_Object*)(&_First->Data);sResult.Add((_string)(*po));}_DListNode<T>* dn = this->_First;while (dn != _Last){po = (_Object*)(&dn->Data);sResult.Add((_string)(*po));sResult.Add(sp);dn = dn->Next;}po = (_Object*)(&_Last->Data);sResult.Add((_string)(*po));}else{if (typeid(T) == typeid(int)){_DListNode<T>* dn = this->_First;while (dn != _Last){int* pInt = (int*)&(dn->Data);sResult.Add(_string::Java_valueOf(*pInt));sResult.Add(sp);dn = dn->Next;}if (this->Count > 0)sResult.Add(_string::Java_valueOf(*((int*)(&(_Last->Data)))));}         else if(typeid(T) == typeid(size_t)){_DListNode<T>* dn = this->_First;while (dn != _Last){size_t* pInt = (size_t*)&(dn->Data);sResult.Add(_string::Java_valueOf(*pInt));sResult.Add(sp);dn = dn->Next;}if (this->Count > 0)sResult.Add(_string::Java_valueOf(*((size_t*)(&(_Last->Data)))));}else if (typeid(T) == typeid(double)){if (_Count == 0) return sResult;double* pd;if (_Count == 1){pd = (double*)(&(_First->Data));sResult.Add(_Convert::DoubleToString(*pd));}_DListNode<T>* dn = this->_First;while (dn != _Last){pd = (double*)&(dn->Data);sResult.Add(_Convert::DoubleToString(*pd));sResult.Add(sp);dn = dn->Next;}pd = (double*)&(_Last->Data);sResult.Add(_Convert::DoubleToString(*pd));}else if (typeid(T) == typeid(_string)){_string* ps;_DListNode<T>* dn = this->_First;while (dn != _Last){ps = (_string*)(&dn->Data);sResult.Add(_t("\""));sResult.Add(*ps);sResult.Add(_t("\""));sResult.Add(sp);dn = dn->Next;}if (_Count > 0){ps = (_string*)(&_Last->Data);sResult.Add(_t("\""));sResult.Add(*ps);sResult.Add(_t("\""));}}else if (typeid(T) == typeid(_StrA)){_StrA* ps;if (_Count <= 0){}else if (_Count == 1){ps = (_StrA*)(&_First->Data);sResult.Add(_t("\""));sResult.Add(*ps);sResult.Add(_t("\""));}else{_DListNode<T>* dn = this->_First;while (dn != _Last){ps = (_StrA*)(&dn->Data);sResult.Add(_t("\""));sResult.Add(*ps);sResult.Add(_t("\""));sResult.Add(_t(','));dn = dn->Next;}ps = (_StrA*)(&_Last->Data);sResult.Add(_t("\""));sResult.Add(*ps);sResult.Add(_t("\""));}}else  //所有继承自 _Object 类的数据类型都可以{sResult.Add(_t("_LDList::ToSplitString重写,数据类型为:"));sResult.Add(_string(typeid(T).name()));            }}sResult.Add(_t("}\n"));return sResult;}inline _string ToString()const{return ToSplitString(_t(""));}}; //--------------------------------------------------------------------------DList//-----------------------------------------------------------------------SortedDList
/// <summary>
///  C#语句:public class SortList<T> : _DList<T>
/// </summary>
/// <typeparam name="T"></typeparam>
template<class T>
class SortedDList : public _DList<T>
{};//----------------------------------------------------------------------StringList
template<class T>
class _StrList : public _DList<T>
{public:  //------------------------------------------------------------------构造与析构 _StrList() : _DList<T>() {};_StrList(const _StrList<T>& sl) : _DList<T>(sl) {};explicit _StrList(const _char* pStr, const _char* pSplit, bool bIgnoreEmptyString = false){this->InitData();SplitForSeparator(pStr, pSplit, bIgnoreEmptyString);}/// <summary>/// 要加上 explicit阻止自动转换, 否则执行语名会自动调用这个构造函数  _StrList  ls = { L"AA",L"BB"};/// </summary>/// <param name="sText"></param>/// <param name="sSplit"></param>/// <param name="bIgnoreEmptyString"></param>explicit _StrList(const T& sText, const T& sSplit, bool bIgnoreEmptyString = false){//assert(sText != null && sSplit != null);//SplitForSeparator(sText.Data, sSplit.Data, bIgnoreEmptyString);if (sText.Length == 0) { return; }if (sSplit.Length == 0) { Add(sText);   return; }int iStart = 0;int iIndex = sText.IndexOf(sSplit, iStart);if (iIndex == -1){Add(sText);return;}while (iIndex != -1 && iStart + 1 <= sText.Length){if (iIndex != iStart)Add(sText.SubStr(iStart, iIndex - iStart));else{if (!bIgnoreEmptyString) Add(T());}iStart = iIndex + sSplit.Length;iIndex = sText.IndexOf(sSplit, iStart);if (iIndex == -1 && sText.Length != iStart)Add(sText.SubStr(iStart, sText.Length - iStart));  //拷贝最后一个}}_StrList(std::initializer_list<T> aList){for (T s : aList){Add(s);}}public: //------------------------------------------------------------------操作void writeToFile(const T& sFullPathName){}bool readToFile(const T& sFullPathName){return false;}bool readToUnicodeFile(const T& sFileName, const T& sSplit){return false;}/// <summary>/// 获取所有字符串的总共长度/// </summary>/// <returns></returns>/// 创建时间:  2022-11-05    最后一次修改时间:  2022-11-05 int GetStringLength() const{int iSum = 0;auto dn = this->_First;while (dn != null) {iSum += (int)dn->Data.Length;dn = dn->Next;}return iSum;}T connectForSeparator(const T& sConnector)const{if (this->_Count == 0) return _t("");if (this->_Count == 1) return this->_First->Data;T tmp(_t(""), GetStringLength() + sConnector.Length * this->_Count + 100);_DListNode<T>* ldNode = this->_First;while (ldNode != this->_Last){tmp += ldNode->Data;tmp += sConnector;ldNode = ldNode->Next;}tmp += this->_Last->Data;       //加入最后一项return tmp;}T connectForSeparator(const _char& cConnector) const{return connectForSeparator(&cConnector);}/// <summary>/// 返回分隔后的字符串列表/// </summary>/// <param name="pStr">原文本</param>/// <param name="pSplit">分隔字符串</param>/// <param name="bIgnoreEmptyString">是否忽略空字符串</param>/// <returns>返回一个字符串列表</returns>/// 创建时间: 2022-10-04     最后一修改时间:2022-10-05       已测试_StrList<T>& SplitForSeparator(const _char* pStr, const _char* pSplit, bool bIgnoreEmptyString){if (pStr == null || pSplit == null){_cout << "在中_StrList::SplitForSeparator中" << L"pStr == null || pSplit == null" << "\n";throw "pStr == null || pSplit == null";}this->ClearData();if (pStr[0] == 0 || pSplit[0] == 0){Add(_t(""), 0, 0);return *this;}int i = 0;int j = 0;int nStart = 0, nEnd = 0;while (pStr[i] != 0) {// _cout << _t("pStr[i] = ") << pStr[i] << _t("\n");  //此句出错,无任何提示bool bFind = true;j = 0;while (pSplit[j] != 0) {if (pStr[i + j] != pSplit[j]) {bFind = false;break;}++j;}if (bFind) {nEnd = i - 1;     //此处如果 nEnd 是 int ,则 nEnd = i - 1 => nEnd = 18446744073709551615 => 溢出错误 if (bIgnoreEmptyString) {if (nStart <= nEnd) {Add(pStr, nStart, nEnd);  //这里应nStart <= nEnd,而不是 nStart < nEnd,因为当 nStart = nEnd 还是有一个字符的}}else {Add(pStr, nStart, nEnd);}nStart = i + j;i = nStart - 1;}++i;}//拷贝右边最后一项if (bIgnoreEmptyString) {if (nStart <= i - 1) {Add(pStr, nStart, (int)i - 1);}}else {Add(pStr, nStart, (int)i - 1);}return *this;}//int SplitForSeparator(const T& sText, const _char& cSplit);int IndexOf(const T& s){int nIndex = 0;auto dn = this->_First;while (dn){if (dn->Data == s) { return nIndex; }++nIndex;dn = dn->Next;}return -1;}int GetMaxSpaceLength(int nTabCount = 9, int nChineseCharactersCount = 3)const{int nMax = 0;auto dn = this->_First;while (dn){int n = gs.s_length_space(dn->Data.Data, nTabCount, nChineseCharactersCount);if (n > nMax) nMax = n;dn = dn->Next;}return nMax;}/// <summary>/// 用tab键使每行等长/// </summary>/// <param name="nTabCount"></param>/// <returns></returns>/// 创建时间:  2022-10-30    最后一次修改时间:  2022-10-30 T equilongTabLine(int nTabCount = 9){this->RemoveHeadTab();int iMax = GetMaxSpaceLength(nTabCount);for (T& s : *this) {int nSapceLength = gs.s_length_space(s.Data);int n = (iMax - nSapceLength) / 9;if (iMax - nSapceLength - n * 9 >= 5)++n;else--n;for (int j = 0; j < n; j++){s.Add(_t("\t"));}}return connectForSeparator(_t('\n')) + _t('\n');}/// <summary>/// 计算所有行,如果每行都有开始处都有 \t ,则每行除去 \t , 除去个数以最少 \t 行为准。/// 例:/// \t\t abc/// \t bcd/// \t\t\t dd/// 运行函数后变成/// \t abc/// bcd/// \t\t dd/// </summary>/// 创建时间:  2022-11-05    最后一次修改时间:  2022-11-05 void RemoveHeadTab(){int iMin = 100000000;for (T& s : *this) {if (s.Length > 0){int iCount = gs.s_headTabCount(s.Data);if (iCount < iMin) { iMin = iCount; }//log::d("iCount=" + iCount.ToString(), s);}}//log::d("iMin=" + iMin.ToString());if (iMin > 0){for (T& s : *this) {s = s.SubStr(iMin, s.Length - iMin);}}}//-----------------------------------------------------------------------虚函数virtual bool Add(const T& item) override{//_cout << item << "\n";return _DList<T>::Add(item);}void Add(const _StrList<T>& ls)   //覆盖 父类重载函数 virtual bool Add(const T& item);{_DListNode<T>* pNode = ls._First;while (pNode != null){Add(pNode->Data);pNode = pNode->Next;}}bool Add(const T& str, int nStartPos, int nEndPos){if (str.Length == 0 || nEndPos - nStartPos < 0){Add(T());}else {int nLength = nEndPos - nStartPos + 1;/*_Mem<_char> m(nLength + 1);for (int i = 0; i < nLength; ++i){m.Data[i] = pStr[nStartPos + i];}m.Data[nLength] = 0;*/Add(str.SubStr(nStartPos, nLength));}return false;}_string  ToSplitString(const _string& sSplitString) const  override{/**  auto dn = this->_First;T sResult;while (dn != this->_Last){           sResult.std_append(dn->Data);                          sResult.std_append(sConnector);dn = dn->Next;}if (this->_Last != null){sResult.std_append(dn->Data);}char c = '\n';sResult.std_append(c );return sResult;*/return _DList<T>::ToSplitString(sSplitString);}
};/// <summary>
/// 不重复的字符串列表
/// </summary>
/// <typeparam name="T"></typeparam>
/// 创建时间: 2023-05-11      最后一次修改时间:2023-05-11
template<class T>  
class _UStrList : public _StrList<T>
{ 
public:/// <summary>/// 加入一个串,如果这个串存在,则把这项移到最后。/// </summary>/// <param name="item"></param>/// 创建时间: ????-??-??      最后一次修改时间:2023-05-11 (已测试)bool Add(const T& item)override{  bool bFind = false;_DListNode<T>* dnTemp = this->_First;while (dnTemp != null){if (dnTemp->Data == item){this->MoveLast(dnTemp);return false;}dnTemp = dnTemp->Next;}_StrList<T>::Add(item);return true;}};/// <summary>
/// 值都是唯一的字符串列表,  Case Insensitive(不区分大小写)
/// </summary>
template<class T>
class _UStrListCI : public _StrList<T>
{public:/// <summary>/// 加入一个串,如果这个串存在,则把这项移到最后。/// </summary>/// <param name="item"></param>/// 创建时间: ????-??-??      最后一次修改时间:2022-02-18bool Add(const T& item)override{bool bFind = false;_DListNode<T>* dnTemp = this->_First;while (dnTemp != null){if (dnTemp->Data.CSharp_ToLower() == item.CSharp_ToLower()){this->MoveLast(dnTemp);return false;}dnTemp = dnTemp->Next;}_StrList<T>::Add(item);return true;}/*/// <summary>/// 返回前面一个值/// </summary>/// <param name="tCurrValue"></param>/// <returns></returns>T& GetForward(T& sCurr){int iIndex = BinarySearch(sCurr);if (iIndex != -1){if (iIndex + 1 < _Count)return this[iIndex + 1];}return null;}/// <summary>/// 返回后面的一个值/// </summary>/// <param name="sCurr"></param>/// <returns></returns>T& GetBack(T& sCurr){int iIndex = BinarySearch(sCurr);if (iIndex != -1){if (iIndex - 1 < _Count && iIndex - 1 >= 0)return this[iIndex - 1];}return null;}*/
};/// <summary>
/// 已排序好的字符串列表
/// </summary>
template<class T>
class _SStrList : public  _StrList<T>
{
public:_SStrList(const _SortOrder so = _SortOrder::s_Minmax){this->_so = so;if (this->_so == _SortOrder::s_null){throw  _t("排序不能为空!");}}//-------------------------------------------------------------------------------重写/// <summary>/// 快速添加字符串,差不多用了8个小时(两天),才写成。/// </summary>/// <param name="s"></param>/// <returns></returns>bool Add(const T& item) override{if (this->_Count < 3){bool bInsert = false;_DListNode<T>* ld = this->_First;while (ld != null){if (this->_so == _SortOrder::s_Maxmin){if (item >= ld->Data){_StrList<T>::InserNodeFront(ld, item); bInsert = true;break;}}else{if (item <= ld->Data){_StrList<T>::InserNodeFront(ld, item); bInsert = true; break;}}ld = ld->Next;}if (!bInsert) _StrList<T>::Add(item);return true;}int nPos = this->_Count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = this->_Count - 1;  //右边远素if (this->_so == _SortOrder::s_Maxmin){_DListNode<T>* ld = null;while (nRight >= 0 && nLeft >= 0){ld = this->IndexOfNode(nPos);if (item >= ld->Data){if (nRight == nLeft || nPos == nLeft){this->InserNodeFront(ld, item);return true;}nRight = nPos - 1;}else{if (nRight == nLeft || nPos == nRight){this->InserNodeBack(ld, item);return true;}nLeft = nPos + 1;}nPos = nLeft + (nRight - nLeft + 1) / 2;}}else{_DListNode<T>* ld = null;while (nRight >= 0 && nLeft >= 0){ld = this->IndexOfNode(nPos);if (item <= ld->Data){if (nRight == nLeft || nPos == nLeft){this->InserNodeFront(ld, item);return true;}nRight = nPos - 1;}else{if (nRight == nLeft || nPos == nRight){this->InserNodeBack(ld, item);return true;}nLeft = nPos + 1;}nPos = nLeft + (nRight - nLeft + 1) / 2;}}return true;}/// <summary>/// 确定某元素是否在列表中/// </summary>/// <param name="item">查找的对象。对于引用类型,该值可以为 null。</param>/// <returns>如果在列表中找到 item,则为 true,否则为 false。</returns>bool Contains(const T& item) override{if (this->_Count == 0) return false;if (this->_Count == 1) return this->_First->Data == item;if (this->_Count == 2) return this->_First->Data == item || this->_First->Next->Data == item;int nPos = (int)this->_Count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = (int)this->_Count - 1;  //右边远素_DListNode<T>* ld = null;if (this->_so == _SortOrder::s_Maxmin){while (nRight >= 0 && nLeft >= 0){ld = this->IndexOfNode(nPos);int iCom = item.CompareTo(ld->Data);if (iCom > 0){if (nRight == nLeft || nPos == nLeft){return false;}nRight = nPos - 1;}else if (iCom < 0){if (nRight == nLeft || nPos == nRight){return false;}nLeft = nPos + 1;}else{return true;}nPos = nLeft + (nRight - nLeft + 1) / 2;}}else{while (nRight >= 0 && nLeft >= 0){ld = this->IndexOfNode(nPos);int iCom = item.CompareTo(ld->Data);if (iCom < 0){if (nRight == nLeft || nPos == nLeft){return false;}nRight = nPos - 1;}else if (iCom > 0){if (nRight == nLeft || nPos == nRight){return false;}nLeft = nPos + 1;}else{return true;}nPos = nLeft + (nRight - nLeft + 1) / 2;}}return false;}};/// <summary>
/// 值都是唯一的字符串列表,且已排好序,区分大小写
/// </summary>
template<class T>
class _SUStrList : public  _SStrList<T>
{
public:bool Add(const T& item)override{if (this->Contains(item))return false;return _SStrList<T>::Add(item);}_SUStrList(_SortOrder so = _SortOrder::s_Minmax) : _SStrList<T>(so){}};/// <summary>
/// UStringListCI_值都是唯一,且已排序的字符串列表,不区分大小写
/// </summary>
template<class T>
class _SUStrListUI : public _SUStrList<T>
{
public:_SUStrListUI(_SortOrder  st) : _SUStrList<T>(st){}/// <summary>/// 确定某元素是否在列表中/// </summary>/// <param name="item">查找的对象。对于引用类型,该值可以为 null。</param>/// <returns>如果在列表中找到 item,则为 true,否则为 false。</returns>bool Contains(const T& item) override{if (this->_Count == 0) return false;if (this->_Count == 1) return this->_First->Data.ToLower().CompareTo(item.ToLower()) == 0;if (this->_Count == 2) return this->_First->Data.ToLower().CompareTo(item.ToLower()) == 0 || this->_First->Next->Data.ToLower().CompareTo(item.ToLower()) == 0;int nPos = (int)this->_Count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = (int)this->_Count - 1;  //右边远素_DListNode<T>* ld = null;if (this->_so == _SortOrder::s_Maxmin){while (nRight >= 0 && nLeft >= 0){ld = this->IndexOfNode(nPos);int iCom = item.ToLower().CompareTo(ld->Data.ToLower());if (iCom > 0){if (nRight == nLeft || nPos == nLeft){return false;}nRight = nPos - 1;}else if (iCom < 0){if (nRight == nLeft || nPos == nRight){return false;}nLeft = nPos + 1;}else{return true;}nPos = nLeft + (nRight - nLeft + 1) / 2;}}else{while (nRight >= 0 && nLeft >= 0){ld = this->IndexOfNode(nPos);int iCom = item.ToLower().CompareTo(ld->Data.ToLower());if (iCom < 0){if (nRight == nLeft || nPos == nLeft){return false;}nRight = nPos - 1;}else if (iCom > 0){if (nRight == nLeft || nPos == nRight){return false;}nLeft = nPos + 1;}else{return true;}nPos = nLeft + (nRight - nLeft + 1) / 2;}}return false;}
};_LF_END_
#endif

2. C#版

/*****************************************************************************创建时间          :  2006年12月19日文件名            : List_.cs作者              : 李锋Email            :   ruizhilf@139.com联系电话          :  13828778863,25722732----------------------最后一次修改时间:2022年10月10日*******************************************************************************/
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text.RegularExpressions;
using System.IO;
using System.Diagnostics;namespace lf
{#region DListNote_(双向链表的节点)/// <summary>/// 双向链表的节点/// </summary>/// <typeparam name="T"></typeparam>public class DListNote_<T>{/// <summary>/// 节点数据/// </summary>public T Data;/// <summary>/// 前一个节点/// </summary>public DListNote_<T> Prev;/// <summary>/// 下一个节点/// </summary>public DListNote_<T> Next;public DListNote_(T aData){Data = aData;            Prev = null;Next = null;}}#endregion#region  Sortord_( 排序方式)/// <summary>/// 排序顺序/// </summary>public enum Sortord_{  s_min_max,   //从小到大   s_max_min,   //从大到小s_null       //无排序顺序}#endregion#region //====================================================== DList_(双向链表)/// <summary>/// 双向链表/// </summary>/// <typeparam name="T"></typeparam>public class DList_<T> : IEnumerable{protected DListNote_<T> _First;			        //第一个节点protected DListNote_<T> _Last;			        //最后一个节点protected int  _Count;			                //节点个数     protected Sortord_ _sortord;                    //排序顺序//------------------------------------------------------------------------------------------属性/// <summary>/// 实际包含的元素数/// </summary>public int Count {get{return _Count;}}        /// <summary>/// 获取或设置指定索引处的元素/// </summary>/// <param name="index">要获得或设置的元素从零开始的索引</param>/// <returns>指定索引处的元素</returns>public virtual T this[int index]{get{return IndexOfNote(index).Data;         }set{IndexOfNote(index).Data = value;            }}//---------------------------------------------------------------------------------构造与析构//---------------------------------------------------------------------------------运算符重载/// <summary>/// /// </summary>/// <param name="dLeft"></param>/// <param name="dlRight"></param>/// <returns></returns>/// 创建时间: 2021-11-07      最后一次修改时间:2021-11-07public static DList_<T> operator +(DList_<T> dLeft, DList_<T> dlRight){/*DList_<T> dlResult = new DList_<T> ();dlResult.Add(dLeft);dlResult.Add(dlRight);return dlResult;*/return new DList_<T> { dLeft, dlRight };}//---------------------------------------------------------------------------------功能函数/// <summary>/// 将指定集合的元素添加到末尾/// </summary>/// <param name="item">要添加到的末尾处的对象。对于引用类型,该值可以为 null</param>/// <returns>如成功,返回真,否则返回假</returns>public virtual void Add(T item){ if (_Count == 0){_First = new DListNote_<T>(item);_First.Next = null;_First.Prev = null;_Last = _First;}else{DListNote_<T> pNew = new DListNote_<T>(item);pNew.Next = null;pNew.Prev = _Last;_Last.Next = pNew;_Last = pNew;}++_Count;_sortord = Sortord_.s_null;   //要重新排序}/// <summary>/// /// </summary>/// <param name="nIndex"></param>/// <param name="item"></param>/// <returns></returns>/// 创建时间: 2022-08-11      最后一次修改时间:2022-08-12public virtual void Insert(int nIndex, T item){if ((uint)nIndex > (uint)_Count){throw new Exception("DList_.Insert 插入位置错误!");}if (nIndex == 0){                if(_First != null){                    DListNote_<T> dnNew = new DListNote_<T>(item);_First.Prev = dnNew;dnNew.Next = _First;_First = dnNew;                     ++_Count;_sortord = Sortord_.s_null;}else{Add(item);}}else if(nIndex == _Count){Add(item);}else{DListNote_<T> dnNew = new DListNote_<T>(item);DListNote_<T> dnNext = IndexOfNote(nIndex);DListNote_<T> dnPrev = dnNext.Prev;dnNew.Next = dnNext;dnNew.Prev = dnPrev;dnNext.Prev = dnNew;dnPrev.Next = dnNew;  ++_Count;_sortord = Sortord_.s_null;}                       }public void  Add(DList_<T> dList){if (dList == null){throw new System.Exception("DList_<T>.Add中参数dList==null");}DListNote_<T> ld = dList._First;while (ld != null){Add(ld.Data);ld =  ld.Next;} }public override string ToString(){string sResult = "";DListNote_<T> dnNote = _First;while (dnNote != null){sResult += dnNote.Data.ToString();sResult += "\n";dnNote = dnNote.Next;}return sResult;}public string ToString(string sSplit){string sResult = "";DListNote_<T> dnNote = _First;while (dnNote != null){sResult += dnNote.Data.ToString();if(dnNote != Last)sResult += sSplit;dnNote = dnNote.Next;}return sResult;}/// <summary>/// 使用指定的比较器在整个已排序的 中搜索元素,并返回该元素从零开始的索引/// </summary>/// <param name="item">要定位的对象。对于引用类型,该值可以为 null。</param>/// <returns>如果找到 item,则为已排序的  的从零开始的索引;否则为-1; </returns>public  int BinarySearch(T item){          switch (_sortord){case Sortord_.s_max_min:{if (Count == 0){return -1;}if (Count == 1){return (_First.Data as IComparable).CompareTo(item) == 0 ? 0 : -1;          }if (Count == 2){if( (_First.Data as IComparable).CompareTo(item) == 0) return 0;if ((_First.Next.Data as IComparable).CompareTo(item) == 0) return 1;return -1;}int nPos = (int)Count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = (int)Count - 1;  //右边远素DListNote_<T> ld;while (nRight >= 0 && nLeft >= 0){ld = IndexOfNote(nPos);int iCom = (item as IComparable).CompareTo(ld.Data);                            if (iCom > 0){if (nRight == nLeft || nPos == nLeft){return -1;}nRight = nPos - 1;}else if (iCom < 0){if (nRight == nLeft || nPos == nRight){return -1;}nLeft = nPos + 1;}else{return nPos;}nPos = nLeft + (nRight - nLeft + 1) / 2;}break;} case Sortord_.s_min_max:{   if (Count == 0){return -1;}if (Count == 1){return (_First.Data as IComparable).CompareTo(item) == 0 ? 0 : -1;           }if (Count == 2){if ((_First.Data as IComparable).CompareTo(item) == 0) return 0;if ((_First.Next.Data as IComparable).CompareTo(item) == 0) return 1;return -1;}int nPos = (int)Count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = (int)Count - 1;  //右边远素DListNote_<T> ld = null;while (nRight >= 0 && nLeft >= 0){ ld = IndexOfNote(nPos);int iCom = (item as IComparable).CompareTo(ld.Data);if (iCom < 0){if (nRight == nLeft || nPos == nLeft){return -1;}nRight = nPos - 1;}else if (iCom > 0){if (nRight == nLeft || nPos == nRight){return -1;}nLeft = nPos + 1;}else{return nPos;}nPos = nLeft + (nRight - nLeft + 1) / 2;}break;}case Sortord_.s_null:{DListNote_<T> pNote = _First;int iCount = 0;while (pNote != null){ if (pNote.Data.Equals(item)){return iCount;}pNote = pNote.Next;++iCount;}break;}default:{return -1;}}return -1;}/*** 功能:清空所有元素的所有数据,并清空链表* 创建时间:????/??/??* 最后一次修改时间:2022-07-02*/public void Clear(){_Count = 0;DListNote_<T> pTemp1 = _First;while (pTemp1 != null){DListNote_<T> pTemp2 = pTemp1.Next;pTemp1.Data = default(T);pTemp1.Next = null;pTemp1.Prev = null;pTemp1 = pTemp2;}_First = null;_Last = null;}/// <summary>/// 确定某元素是否在列表中/// </summary>/// <param name="item">查找的对象。对于引用类型,该值可以为 null。</param>/// <returns>如果在列表中找到 item,则为 true,否则为 false。</returns>public virtual bool Contains(T item){   return BinarySearch(item) != -1;             }/// <summary>/// 复制一个链表,清除原来链表的数据/// </summary>/// <param name="ld"></param>public void CopyFrom(DList_<T> ld){         if (!this.Equals(ld)){Clear();DListNote_<T> ldItem = ld._First;while (ldItem != null){Add(ldItem.Data);ldItem = ldItem.Next;}}}/*public int IndexOf(T item){return -1;}public int IndexOf(T item, int index){return -1;}public void Insert(int index, T item){}public int LastIndexOf(T item){return -1;}public int LastIndexOf(T item, int index, int Count){return -1;}*//// <summary>/// 移除指定索引处的元素/// </summary>/// <param name="iIndex">要移除的元素的从零开始的索引。</param>/// <returns>成功返回true,否则返回false</returns>public bool RemoveAt(int iIndex){                   if (iIndex < 0 || iIndex + 1 > _Count) { return false; }DListNote_<T> pNode = _First;int iCount = 0;while (pNode != null){if (iCount == iIndex){if (pNode == _First){                        if (_First.Next == null)   //只有一个{      Clear();return true; }         else   {_First = _First.Next;_First.Prev = null;--_Count;                     return true;}}else if (pNode == _Last){if (_Last.Prev == null){Clear();return true;}else{                            _Last = _Last.Prev;_Last.Next = null;                     --_Count;return true;}}else{pNode.Prev.Next = pNode.Next;pNode.Next.Prev = pNode.Prev;pNode = null;--_Count;return true;}}pNode = pNode.Next;++iCount;}return false;}/// <summary>///  反向排列链表/// </summary>/// 创建时间: 2022-04-20      最后一次修改时间:2022-04-20public virtual void Reverse(){DListNote_<T> dnTemp = First;while(dnTemp != null){LMath.Swap(ref dnTemp.Next, ref dnTemp.Prev);dnTemp = dnTemp.Prev;}LMath.Swap(ref _First, ref _Last);            }/// <summary>/// 添加一个元素,并把它放在首位,其它元素后移,如棵后面的元素删除,总无素个数不变,如果无素个数为零,则添加一个无素。/// </summary>/// <param name="Item"></param>/// <param name="bRemoveLast"></param>/// 创建时间: 2022-04-19      最后一次修改时间:2022-04-19public void StackPush(T Item, bool bRemoveLast = false){if (_Count == 0){Add(Item);}else if (_Count == 1){if (bRemoveLast){_First.Data = Item;}else{//把无素放在最前DListNote_<T> dnNew = new DListNote_<T>(Item);_First.Prev = dnNew;dnNew.Next = _First;_First = dnNew;++_Count;}}else{if (bRemoveLast){//删除最后一个元素_Last = _Last.Prev;_Last.Next = null;//把无素放在最前DListNote_<T> dnNew = new DListNote_<T>(Item);_First.Prev = dnNew;dnNew.Next = _First;dnNew.Prev = null;_First = dnNew;}else {//把无素放在最前DListNote_<T> dnNew = new DListNote_<T>(Item);_First.Prev = dnNew;dnNew.Next = _First;dnNew.Prev = null;_First = dnNew;++_Count;}                 }   }/// <summary>/// 删除第一个元素,出栈/// </summary>/// 创建时间: 2022-04-19      最后一次修改时间:2022-04-19public void StackPop(){ RemoveAt(0); }/// <summary>/// 转换成数组/// </summary>/// <returns></returns>public T[] ToArray(){T[]  aResult = new T[Count];int n = 0;DListNote_<T> pNoteTemp = _First;while (pNoteTemp != null){aResult[n++] = pNoteTemp.Data;pNoteTemp = pNoteTemp.Next;}return aResult;}/// <summary>/// 交换两个节点的数据/// </summary>/// <param name="nIndex1"></param>/// <param name="nIndex2"></param>/// <returns></returns>protected virtual bool swapNoteData(int iIndex1, int iIndex2){ DListNote_<T> pNote1, pNote2;pNote1 = IndexOfNote(iIndex1);pNote2 = IndexOfNote(iIndex2);if (!(pNote1 != null && pNote2 != null)){return false;}T ptmp = pNote1.Data;pNote1.Data = pNote2.Data;pNote2.Data = ptmp;return true;}/// <summary>/// 选择排序可以说是最简单的一种排序方法:/// 1.找到数组中最小的那个元素/// 2.将最小的这个元素和数组中第一个元素交换位置/// 3.在剩下的元素中找到最小的的元素,与数组第二个元素交换位置/// 重复以上步骤,即可以得到有序数组。/// </summary>public virtual void sort_selection(Sortord_ sortord){if (_Count == 0 || _Count == 1) return;//is关键字用于检查对象是否与给定类型兼容。注意了,这里is并不是“是”的意思,而是“兼容”。if (!(_First.Data is IComparable)) // 判断是否具有IComparable接口,以确定是否存在CompareTo()方法{throw new Exception("没有IComparable接口");}           DListNote_<T> min = _First, tmp = _First.Next;if (sortord == Sortord_.s_min_max){while (min.Next != null){while (tmp != null){if ((tmp.Data as IComparable).CompareTo(min.Data) < 0)  //交换位置{T pt = tmp.Data;       tmp.Data = min.Data;min.Data = pt;}tmp = tmp.Next;}min = min.Next;tmp = min.Next;}}else{while (min.Next != null){while (tmp != null){if ((tmp.Data as IComparable).CompareTo(min.Data) > 0){T pt = tmp.Data;tmp.Data = min.Data;min.Data = pt;}tmp = tmp.Next;}min = min.Next;tmp = min.Next;}}_sortord = sortord;  //已排序}/// <summary>/// 返回索引的节点,从零开始/// </summary>/// <param name="nPos"></param>/// <returns></returns>public virtual DListNote_<T> IndexOfNote(int iPos){          if (iPos >= _Count || iPos < 0) throw new System.Exception("DListNote_<T>.IndexOfNote  错误索引: " + iPos.ToString() + "!");uint nindex = 0;if (iPos > _Count / 2){DListNote_<T> pNote = _Last;while (pNote != null){if (nindex++ == _Count - iPos - 1){ return pNote;}pNote = pNote.Prev;}}else{DListNote_<T> pNote = _First;while (pNote != null){if (nindex++ == iPos){             return pNote;}pNote = pNote.Next;}}return null;}/// <summary>/// 在结点pListItem前面插入一个结点,成功,返回新的结点,否则返回0/// </summary>/// <param name="pListItem"></param>/// <param name="pData"></param>/// <returns></returns>protected virtual DListNote_<T> InserNoteFront(DListNote_<T> pListItem, T pData){if (pListItem == null){throw new System.Exception("函数提示:pListItem = null");}DListNote_<T> pNote = new DListNote_<T>(pData);//pNote            pNote.Next = pListItem;pNote.Prev = pListItem.Prev;//--pListItem->Previf (pListItem.Prev != null){pListItem.Prev.Next = pNote;}else{_First = pNote;}//pListItempListItem.Prev = pNote;++_Count;return pNote;}/// <summary>/// 在结点pListItem后面插入一个结点,成功,返回新的结点,否则返回0;/// </summary>/// <param name="pListItem"></param>/// <param name="pData"></param>/// <returns></returns>protected virtual DListNote_<T> InserNoteBack(DListNote_<T> pListItem, T pData){if (pListItem == null) return null;DListNote_<T> pNote = new DListNote_<T>(pData);//pNotepNote.Prev = pListItem;pNote.Next = pListItem.Next;//pListItem->Nextif (pListItem.Next != null){pListItem.Next.Prev = pNote;}else{_Last = pNote;}//--pListItempListItem.Next = pNote;++_Count;return pNote;}/// <summary>/// 找查一个项,而不是节点,返回的这个节点相当于指针。/// </summary>/// <param name="pData">项值</param>/// <returns></returns>public  DListNote_<T> FindNoteItem(T item){switch (_sortord){case Sortord_.s_max_min:{if (Count == 0){return null;}if (Count == 1){return (_First.Data as IComparable).CompareTo(item) == 0 ? _First : null;}if (Count == 2){if ((_First.Data as IComparable).CompareTo(item) == 0) return _First;if ((_First.Next.Data as IComparable).CompareTo(item) == 0) return _First.Next;return null;}int nPos = (int)Count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = (int)Count - 1;  //右边远素DListNote_<T> ld = null;while (nRight >= 0 && nLeft >= 0){ld = IndexOfNote(nPos);int iCom = (item as IComparable).CompareTo(ld.Data);if (iCom > 0){if (nRight == nLeft || nPos == nLeft){return null;}nRight = nPos - 1;}else if (iCom < 0){if (nRight == nLeft || nPos == nRight){return null;}nLeft = nPos + 1;}else{return ld;}nPos = nLeft + (nRight - nLeft + 1) / 2;}break;}case Sortord_.s_min_max:{if (Count == 0){return null;}if (Count == 1){return (_First.Data as IComparable).CompareTo(item) == 0 ? _First : null;}if (Count == 2){if ((_First.Data as IComparable).CompareTo(item) == 0) return _First;if ((_First.Next.Data as IComparable).CompareTo(item) == 0) return _First.Next;return null;}int nPos = (int)Count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = (int)Count - 1;  //右边远素DListNote_<T> ld = null;while (nRight >= 0 && nLeft >= 0){ld = IndexOfNote(nPos);int iCom = (item as IComparable).CompareTo(ld.Data);if (iCom < 0){if (nRight == nLeft || nPos == nLeft){return null;}nRight = nPos - 1;}else if (iCom > 0){if (nRight == nLeft || nPos == nRight){return null;}nLeft = nPos + 1;}else{return ld;}nPos = nLeft + (nRight - nLeft + 1) / 2;}break;}case Sortord_.s_null:{DListNote_<T> pNote = _First;                   while (pNote != null){//总结:Equals比较的永远是变量的内容是否相同,而= =比较的则是引用地址是否相同(前提:此种类型内部没有对Equals 或= = 进行重写操作,//否则输出可能会有不同)。string 类型是个特例,因为他的内部对这两个都进行了重写。if ((item as IComparable).CompareTo(pNote.Data) == 0){return pNote;}/*if (pNote.Data.Equals(item)){return pNote;}*/pNote = pNote.Next;                        }break;}default:{return null;}}return null;}/// <summary>/// 把索引为nIndex的节点移到最后/// </summary>/// <param name="nIndex"></param>/// <returns></returns>protected virtual bool MoveLast(int iIndex){DListNote_<T> pNote = IndexOfNote(iIndex);if (pNote != null){if (pNote == _Last)return true;if (pNote == _First) //此时最少两个节点{_First = _First.Next;_First.Prev = null;_Last.Next = pNote;pNote.Prev = _Last;_Last = pNote;}else{pNote.Prev.Next = pNote.Next;pNote.Next.Prev = pNote.Prev;_Last.Next = pNote;pNote.Prev = _Last;_Last = pNote;}return true;}return false;}/// <summary>/// /// </summary>/// <param name="dnCurrent"></param>/// <returns></returns>/// 创建时间: 2022-02-18      最后一次修改时间:2022-02-18protected virtual bool MoveLast(DListNote_<T> dnCurrent){if (dnCurrent == null) return false;_sortord = Sortord_.s_null;if(_Count == 0){return false;}else if(_Count == 1){return true;}else if(_Count == 2)  {if(dnCurrent == _First)  //交换_First 与 _Last 数据{              T tmp = _First.Data;_First.Data = _Last.Data;_Last.Data = tmp;                     }return true;}else{if (dnCurrent == _First){_First = _First.Next;_First.Prev = null;_Last.Next = dnCurrent;dnCurrent.Next = null;dnCurrent.Prev = _Last;_Last = dnCurrent;}else if (dnCurrent != _Last){dnCurrent.Prev.Next = dnCurrent.Next;dnCurrent.Next.Prev = dnCurrent.Prev;_Last.Next = dnCurrent;dnCurrent.Next = null;dnCurrent.Prev = _Last;_Last = dnCurrent;}return true;}}/// <summary>/// 把索引为nIndex的节点移到最前/// </summary>/// <param name="nIndex"></param>/// <returns></returns>protected virtual bool MoveFirst(int iIndex){DListNote_<T> pNote = IndexOfNote(iIndex);if (pNote != null){if (pNote == _First)return true;if (pNote == _Last)  //此时最少两个节点{_Last.Prev.Next = null;_Last = _Last.Prev;pNote.Prev = null;pNote.Next = _First;_First.Prev = pNote;_First = pNote;}else{pNote.Prev.Next = pNote.Next;pNote.Next.Prev = pNote.Prev;pNote.Next = _First;_First.Prev = pNote;pNote.Prev = null;_First = pNote;}return true;}return false;}/// <summary>/// 返回第一个节点/// </summary>public  DListNote_<T> First{get{          return _First; }}  /// <summary>/// 返回最后一个节点/// </summary>public  DListNote_<T> Last{get {  return _Last;   }}//--------------------------------------------------------------------------------------/// <summary>/// 构造函数/// </summary>public DList_(){_Count = 0; _First = null; _Last = null;  _sortord = Sortord_.s_null;}/// <summary>/// 删除链表中的数据/// </summary>/// <param name="pData"></param>/// <returns></returns>public bool RemoveItem(T pData){if (_sortord == Sortord_.s_null){DListNote_<T> pListItem = _First;while (pListItem != null){if (pListItem.Data.Equals(pData))	//找到一项{if (pListItem == _First)		//删除的是第一个节点{if (_First.Next != null){_First.Next.Prev = null;_First = _First.Next;}else{_First = null;_Last = null;}}else if (pListItem == _Last)  //删除的是最后一个节点{if (_Last.Prev != null){_Last.Prev.Next = null;_Last = _Last.Prev;}else{_First = null;_Last = null;}}else						//删除的是中间的一个节点{pListItem.Next.Prev = pListItem.Prev;pListItem.Prev.Next = pListItem.Next;}--_Count;return true;}pListItem = pListItem.Next;}return false;}else{return RemoveAt(BinarySearch(pData));}}/// <summary>/// 删除链表中的节点/// </summary>/// <param name="pListItem"></param>/// <returns></returns>public bool DeleteNode(DListNote_<T> pListItem){if (_Count == 0 || pListItem == null){return false;}DListNote_<T> pNote = _First.Next;while (pNote != null){if (pNote == pListItem)  //找到了{//pListItem->Previf (pListItem.Prev != null){pListItem.Prev.Next = pListItem.Next;}else //删除的是第一个节点{_First = pListItem.Next;}//pListItem->Nextif (pListItem.Next != null){pListItem.Next.Prev = pListItem.Prev;}else //删除的是最后一个节点{_Last = pListItem.Prev;}break;}pNote = pNote.Next;}if (pNote != null){--_Count;return true;}return false;}/// <summary>/// 删除最后一个节点/// </summary>/// 创建时间:2020-09-12  最后一次修改时间: 2020-09-12public bool DeleteLast(){if (_Count <= 0){return false;}else if (_Count == 1){_First = null;_Last = null;_Count = 0;return true;}else if(_Count == 2){_Last = _First;_Last.Prev = null;_Last.Next = null;_First.Next = null;_First.Prev = null;--_Count;}else{_Last.Prev.Next = null;_Last = _Last.Prev;--_Count;}return true; ;             }//--------------------------------------------------------------------------接口/// <summary>//示例为了使一个类支持集合初始化器,它必须实现IEnumerable接口并至少具有一个Add方法。从C#6开始,//IEnumerable可以Add使用扩展方法使用自定义方法扩展任何实现的集合。/// </summary>/// 创建时间:2020-05-07  最后一次修改时间: 2020-05-07/// <returns></returns>public IEnumerator GetEnumerator(){ return new DListNoteEnum_<T>(_First);}   }/// <summary>/// 节点数据的foreach迭代/// </summary>/// 创建时间:2020-05-07  最后一次修改时间: 2022-10-10/// <typeparam name="T"></typeparam>public class DListNoteEnum_<T> : IEnumerator{private DListNote_<T> _dn;private DListNote_<T> _dnCurr;private int _iIndex;public DListNoteEnum_(DListNote_<T> dn){_dn = dn;_iIndex = -1;}/// <summary>/// IEnumerator最终调用的是这个函数访问/// </summary>public Object Current {  get{  return _dnCurr.Data; }  }public virtual bool MoveNext(){++_iIndex; //指针首先向前移动一位if (_dnCurr == null){_dnCurr = _dn;}else{_dnCurr = _dnCurr.Next;}return _dnCurr != null;}public virtual void Reset(){_dnCurr = null;_iIndex = -1;}};#endregion#region//====================================================== SortList_ 已排序的链表
/// <summary>
/// 已排序的链表
/// </summary>
/// <typeparam name="T"></typeparam>
public class SortList_<T> : DList_<T>{public SortList_(Sortord_ sortord){_sortord = sortord;}//-------------------------------------------------------------------------------重写/// <summary>/// 添加一项到结尾处,item不能为NULL./// </summary>/// <param name="item">项</param>/// 创建时间: ????-??-??      最后一次修改时间:2021-11-07public override void Add(T item){   if (item == null){throw new System.Exception("SortList_.Add 方法提示:类型值不能为null!");}if ( !(item is IComparable) ) // 判断是否具有IComparable接口,以确定是否存在CompareTo()方法{throw new System.Exception("SortList_<" + item.GetType().Name + ">.Add 方法提示:类型“" + item.GetType().Name + "”没有IComparable接口!");}if (Count < 3){bool bInsett = false; DListNote_<T> ldNote = First;while (ldNote != null){if (_sortord == Sortord_.s_max_min){if ((item as IComparable).CompareTo(ldNote.Data) >= 0){base.InserNoteFront(ldNote, item); bInsett = true; break;}}else{if ((item as IComparable).CompareTo(ldNote.Data) <= 0){base.InserNoteFront(ldNote, item); bInsett = true; break;}}ldNote = ldNote.Next;}if (!bInsett) base.Add(item);return;}int nPos = Count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = Count - 1;  //右边远素if (_sortord == Sortord_.s_max_min){DListNote_<T> ldNote = null;while (nRight >= 0 && nLeft >= 0){ldNote = IndexOfNote(nPos);if ((item as IComparable).CompareTo(ldNote.Data) >= 0){if (nRight == nLeft || nPos == nLeft){InserNoteFront(ldNote, item);return;}nRight = nPos - 1;}else{if (nRight == nLeft || nPos == nRight){InserNoteBack(ldNote, item); return;}nLeft = nPos + 1;}nPos = nLeft + (nRight - nLeft + 1) / 2;}}else{DListNote_<T> ld = null;while (nRight >= 0 && nLeft >= 0){ld = IndexOfNote(nPos);if ((item as IComparable).CompareTo(ld.Data) <= 0){if (nRight == nLeft || nPos == nLeft){InserNoteFront(ld, item); return;}nRight = nPos - 1;}else{if (nRight == nLeft || nPos == nRight){InserNoteBack(ld, item);return;}nLeft = nPos + 1;}nPos = nLeft + (nRight - nLeft + 1) / 2;}}return;}}#endregion#region//================================================= UniqueList_ 每个项的值都是唯一的链表/// <summary>/// 每个项的值都是唯一的链表 /// </summary>/// <typeparam name="T"></typeparam>public class UniqueList_<T> : DList_<T>{public override void Add(T item){         if (BinarySearch(item) == -1){base.Add(item);}}}#endregion#region //========================== =========SUList_,已排序,且每一项的值都是唯一的链表/// <summary>/// SUList_,已排序,且每一项的值都是唯一的链表/// </summary>/// <typeparam name="T"></typeparam>public class SUList_<T> : SortList_<T>{/// <summary>/// 将指定集合的元素添加到末尾/// </summary>/// <param name="item">要添加到的末尾处的对象。对于引用类型,该值可以为 null</param>/// <returns>如成功,返回真,否则返回假</returns>public override void Add(T item){           if (BinarySearch(item) == -1){base.Add(item);}    }public SUList_(Sortord_ sortord): base(sortord){}}#endregion#region //=========================================StringList_字符串列表/// <summary>/// 字符串列表/// </summary>public class StringList_ : DList_<string>{/// <summary>/// 默认构函数/// </summary>public StringList_()   {}/// <summary>/// 以分隔符构造一个字符串列表/// </summary>/// <param name="sText">原文字符串</param>/// <param name="sSplit">分隔符</param>/// <param name="bIgnoreEmptyString">返回列表,空字符串不忽略,如果没有分隔符,则回原字符</param>/// 创建时间: ????-??-??     最后一修改时间:2020-09-03public StringList_(string sText, string sSplit, bool bIgnoreEmptyString = false){if(sText == null || sText.Length == 0){ return; }if(sSplit.Length == 0)  {  Add(sText);   return;  }int nPos = sText.IndexOf(sSplit);int nFindStart = 0;while(nPos != -1){if (nPos - nFindStart == 0){if (!bIgnoreEmptyString){Add("");}               }else{Add(sText.Substring(nFindStart, nPos - nFindStart));}nFindStart = nPos + sSplit.Length;nPos = sText.IndexOf(sSplit, nFindStart);if(nPos == -1)  //拷贝最后一个{if(nFindStart < sText.Length){Add(sText.Substring(nFindStart, sText.Length - nFindStart));}else{if (!bIgnoreEmptyString){Add("");}}}}}#if !WINDOWS_UWP/// <summary>/// 把列表写入文件/// </summary>/// <param name="sFileName">文件名</param>public void WriteToFile(string sFileName){System.IO.File.Delete(sFileName);DListNote_<string> dl = First;FileStream fs = File.Create(sFileName);     while (dl != null){byte[] bArray = System.Text.Encoding.Default.GetBytes(dl.Data);fs.Write(bArray, 0, bArray.Length);bArray =   System.Text.Encoding.Default.GetBytes("\r\n");//fs.WriteByte((byte)'\r');  不行,UNICODE代码//fs.WriteByte((byte)'\n');fs.Write(bArray, 0, bArray.Length);dl = dl.Next;}fs.Close();}/// <summary>/// 从文件中读取列表分隔符为"\r\n";/// </summary>/// <param name="sFileName">文件名</param>/// <returns></returns>public bool ReadToFile(string sFileName){if (File.Exists(sFileName)){FileStream fs = new FileStream(sFileName, FileMode.Open, FileAccess.Read);Byte[] bArray = new Byte[fs.Length];fs.Read(bArray, 0, bArray.Length);fs.Close();CopyFrom(System.Text.Encoding.Default.GetString(bArray)._Split("\r\n"));return true;}return false;}/// <summary>/// 从文件中读取列表分隔符/// </summary>/// <param name="sFileName"></param>/// <param name="sSplit"></param>/// <returns></returns>public bool readToUnicodeFile(string sFileName,string sSplit){if (File.Exists(sFileName)){FileStream fs = new FileStream(sFileName, FileMode.Open, FileAccess.Read);Byte[] bArray = new Byte[fs.Length];fs.Read(bArray, 0, bArray.Length);fs.Close();CopyFrom(System.Text.Encoding.Unicode.GetString(bArray)._Split(sSplit));return true;}return false;}public void SaveToUnicodeFile(string sFileName, string sSplit){/*if(_Count > 0){ string sContent = "";int n = 1;foreach(string s in this){sContent += s;if(n != _Count)sContent += sSplit;  }Byte[] bArray = System.Text.ASCIIEncoding.ASCII.GetBytes(sContent);FileStream fs = new FileStream(sFileName, FileMode.Create, FileAccess.Write);fs.Write(bArray, 0, bArray.Length);fs.Close();}*/}/// <summary>/// 把所有字符串写入磁盘,但每个字符串中的空格和不可打印字符都不会写入,每15个字符串加入一个换行符。/// </summary>/// <param name="sFileName"></param>/// <param name="sSplit"></param>/// 创建时间: 2022-02-09      最后一次修改时间:2022-02-09 public void WriteToTxtFile(string sFileName, string sSplit){ if (_Count > 0){string sContent = "";int n = 1;foreach (string s in this){                   sContent += s._RemoveUnprintableAndWhitespace();if (n != _Count)sContent += sSplit;if(n % 15 == 0)sContent += "\n";   ++n;}File.WriteAllText(sFileName,sContent);}}/// <summary>/// 用分隔 符读取文本文件,空格和不可打印字符都不读取。/// </summary>/// <param name="sFileName"></param>/// <param name="sSplit"></param>/// 创建时间: 2022-02-09      最后一次修改时间:2022-02-18 public void ReadFromTxtFile(string sFileName, string sSplit){if (!File.Exists(sFileName))return;string sContent = File.ReadAllText(sFileName)._RemoveUnprintableAndWhitespace();if(sContent.Trim().Length > 0){CopyFrom(sContent._Split(sSplit));  } }
#endif/// <summary>/// 用分隔符把每个项连成一片,如果分隔符为空,则直接连成一片/// </summary>/// <param name="sSeparator">分隔符</param>/// <returns></returns>public string ConnectForSeparator(string  sSeparator){if (Count == 0) return "";if (Count == 1) return First.Data;string tmp = "";DListNote_<string> ldNote = First;while (ldNote != Last){tmp += ldNote.Data;tmp += sSeparator;ldNote = ldNote.Next;}tmp += Last.Data;       //加入最后一项return tmp;}/// <summary>/// 用分隔符把每个项连成一片,如果分隔符为空,则直接连成一片/// </summary>/// <param name="cSeparator">分隔符</param>/// <returns></returns>public string ConnectForSeparator(char cSeparator){return ConnectForSeparator(cSeparator.ToString());}/// <summary>/// 清空列表,用分隔符把字符串分裂成多项,返回项数/// </summary>/// <param name="sText"></param>/// <param name="sSplit"></param>/// <returns></returns>public int splitForSeparator(string sText, char cSplit){Clear();string[] sl = sText.Split(cSplit);for (int i = 0; i < sl.Length; ++i){Add(sl[i]);}return Count;}/// <summary>/// 查找第一个可印的字符串,如果找到则返回它的值,没找到返回空字符中。/// </summary>/// <returns></returns>/// 创建时间: 2022-01-21      最后一次修改时间:2022-01-21public string FindFirstPrintableStringValue(){DListNote_<string> pNote = _First;while (pNote != null){if(pNote.Data._IsHavePrintableChar()){return pNote.Data;}pNote = pNote.Next;}return "";}/// <summary>/// 查找第一个可印的字符串的索引,如果找到则返回它的索引,没找到返回-1。/// </summary>/// <returns></returns>/// 创建时间: 2022-01-21      最后一次修改时间:2022-01-21public int FindFirstPrintableStringIndex(){DListNote_<string> pNote = _First;int nResult = 0;while (pNote != null){if (pNote.Data._IsHavePrintableChar()){return nResult;}pNote = pNote.Next;++nResult;}return -1;}/// <summary>/// /// </summary>/// <param name="ls"></param>/// <returns></returns>/// 创建时间: ????-??-??      最后一次修改时间:2021-10-10public virtual bool Add(StringList_ ls){DListNote_<string> pNote = ls._First;while (pNote != null){Add(pNote.Data);pNote = pNote.Next;}return true;     }/// <summary>/// 是开头插入一个字符串/// </summary>/// <param name="sItem"></param>/// <returns></returns>/// 创建时间: 2022-01-18      最后一次修改时间:2022-01-18public virtual bool InserFront(string sItem){if(_Count == 0)Add(sItem);InserNoteFront(_First,sItem);return true;}/// <summary>/// 查找字符吕 S /// </summary>/// <param name="s"></param>/// <returns></returns>/// <exception cref="Exception"></exception>/// 创建时间: ????-??-??      最后一次修改时间:2022-09-18public int IndexOf(string s){//if(s.Length == 0){ throw new Exception("字符串不能为空!");}    DListNote_<string> pNote = _First;int iIndex = 0;while (pNote != null){if (pNote.Data == s){return iIndex;}pNote = pNote.Next;++iIndex;}return - 1;}}#endregion#region //=========================================LSStringList已排序好的字符串列表/// <summary>/// 已排序好的字符串列表/// </summary>public class SStringList_ : StringList_{public SStringList_(Sortord_ sortord){if (sortord == Sortord_.s_null){throw  new System.Exception("排序不能为空!");}_sortord = sortord;}//-------------------------------------------------------------------------------重写/// <summary>/// 快速添加字符串,差不多用了8个小时(两天),才写成。/// </summary>/// <param name="s"></param>/// <returns></returns>public override void Add(string item){ if (Count < 3){bool bInsett = false;      DListNote_<string> ld = First;while (ld != null){if (_sortord == Sortord_.s_max_min){if (item.CompareTo(ld.Data) >= 0){base.InserNoteFront(ld, item); bInsett = true; break;}}else{if (item.CompareTo(ld.Data) <= 0){base.InserNoteFront(ld, item); bInsett = true; break;}}ld = ld.Next;               }if (!bInsett) base.Add(item);return;}int nPos = Count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = Count - 1;  //右边远素if (_sortord == Sortord_.s_max_min){DListNote_<string> ld = null;while (nRight >= 0 && nLeft >= 0){ld = IndexOfNote(nPos);if (item.CompareTo(ld.Data) >= 0){if (nRight == nLeft || nPos == nLeft){InserNoteFront(ld, item); return;}nRight = nPos - 1;}else{if (nRight == nLeft || nPos == nRight){InserNoteBack(ld, item);return;}nLeft = nPos + 1;}nPos = nLeft + (nRight - nLeft + 1) / 2;}}else{DListNote_<string> ld = null;while (nRight >= 0 && nLeft >= 0){ld = IndexOfNote(nPos);if (item.CompareTo(ld.Data) <= 0){if (nRight == nLeft || nPos == nLeft){InserNoteFront(ld, item);return;}nRight = nPos - 1;}else{if (nRight == nLeft || nPos == nRight){InserNoteBack(ld, item); return;}nLeft = nPos + 1;}nPos = nLeft + (nRight - nLeft + 1) / 2;}}return;}/// <summary>/// 确定某元素是否在列表中/// </summary>/// <param name="item">查找的对象。对于引用类型,该值可以为 null。</param>/// <returns>如果在列表中找到 item,则为 true,否则为 false。</returns>public override bool Contains(string item){if (Count == 0) return false;if (Count == 1) return First.Data.CompareTo(item) == 0;if (Count == 2) return First.Data.CompareTo(item) == 0 || First.Next.Data.CompareTo(item) == 0;int nPos = (int)Count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = (int)Count - 1;  //右边远素DListNote_<string> ld = null;if (_sortord == Sortord_.s_max_min){while (nRight >= 0 && nLeft >= 0){ld = IndexOfNote(nPos);int iCom = item.CompareTo(ld.Data);if (iCom > 0){if (nRight == nLeft || nPos == nLeft){return false;}nRight = nPos - 1;}else if (iCom < 0){if (nRight == nLeft || nPos == nRight){return false;}nLeft = nPos + 1;}else{return true;}nPos = nLeft + (nRight - nLeft + 1) / 2;}}else{while (nRight >= 0 && nLeft >= 0){ld = IndexOfNote(nPos);int iCom = item.CompareTo(ld.Data);if (iCom < 0){if (nRight == nLeft || nPos == nLeft){return false;}nRight = nPos - 1;}else if (iCom > 0){if (nRight == nLeft || nPos == nRight){return false;}nLeft = nPos + 1;}else{return true;}nPos = nLeft + (nRight - nLeft + 1) / 2;}}return false;}}
#endregion#region //=========================================UStringList_值都是唯一的字符串列表,区分大小写/// <summary>/// 值都是唯一的字符串列表/// </summary>/// <typeparam name="T"></typeparam>public class UStringList_ : StringList_{public override void Add(string item){if(BinarySearch(item) == -1)base.Add(item);}public void Add(string[] sArray){for (int i = 0; i < sArray.Length; ++i){Add(sArray[i]);}}public override bool Add(StringList_ ls){    bool bResult = true;DListNote_<string> pFirst = ls.First;while (pFirst != null){if (BinarySearch(pFirst.Data) == -1){base.Add(pFirst.Data);}else{bResult = false;}pFirst = pFirst.Next;}return bResult;}}
#endregion#region//======================================SUStringList_ 值都是唯一的字符串列表,且已排好序,区分大小写/// <summary>/// 值都是唯一的字符串列表,且已排好序,区分大小写/// </summary>public class SUStringList_ : SStringList_{ public override void Add(string item){if (Contains(item)) return;base.Add(item); }public SUStringList_(Sortord_ sortord): base(sortord){}}#endregion#region //=========================================UStringListCI_值都是唯一的字符串列表,不区分大小写/// <summary>/// 值都是唯一的字符串列表,  Case Insensitive(不区分大小写)/// </summary>public class UStringListCI_ : StringList_{/// <summary>/// 加入一个串,如果这个串存在,则把这项移到最后。/// </summary>/// <param name="item"></param>/// 创建时间: ????-??-??      最后一次修改时间:2022-02-18public override void Add(string item){bool bFind = false;DListNote_<string> dnTemp = First;while(dnTemp != null){if(dnTemp.Data.ToLower() == item.ToLower()){MoveLast(dnTemp);bFind = true;break;}dnTemp = dnTemp.Next;}if (!bFind)base.Add(item);}/// <summary>/// 返回前面一个值/// </summary>/// <param name="tCurrValue"></param>/// <returns></returns>public string GetForward(string sCurr){int iIndex = BinarySearch(sCurr);if (iIndex != -1){if (iIndex + 1 < Count)return this[iIndex + 1];}return null;}/// <summary>/// 返回后面的一个值/// </summary>/// <param name="sCurr"></param>/// <returns></returns>public string GetBack(string sCurr){int iIndex = BinarySearch(sCurr);if (iIndex != -1){if (iIndex - 1 < Count && iIndex - 1 >= 0)return this[iIndex - 1];}return null;}}
#endregion#region //=========================================UStringListCI_值都是唯一,且已排序的字符串列表,不区分大小写/// <summary>/// UStringListCI_值都是唯一,且已排序的字符串列表,不区分大小写/// </summary>public class SUStringListUI_ : SUStringList_{public  SUStringListUI_(Sortord_ sortord): base(sortord) {}/// <summary>/// 确定某元素是否在列表中/// </summary>/// <param name="item">查找的对象。对于引用类型,该值可以为 null。</param>/// <returns>如果在列表中找到 item,则为 true,否则为 false。</returns>public override bool Contains(string item){if (Count == 0) return false;if (Count == 1) return First.Data.ToLower().CompareTo(item.ToLower()) == 0;if (Count == 2) return First.Data.ToLower().CompareTo(item.ToLower()) == 0 || First.Next.Data.ToLower().CompareTo(item.ToLower()) == 0;int nPos = (int)Count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = (int)Count - 1;  //右边远素DListNote_<string> ld = null;if (_sortord == Sortord_.s_max_min){while (nRight >= 0 && nLeft >= 0){ld = IndexOfNote(nPos);int iCom = item.ToLower().CompareTo(ld.Data.ToLower());if (iCom > 0){if (nRight == nLeft || nPos == nLeft){return false;}nRight = nPos - 1;}else if (iCom < 0){if (nRight == nLeft || nPos == nRight){return false;}nLeft = nPos + 1;}else{return true;}nPos = nLeft + (nRight - nLeft + 1) / 2;}}else{while (nRight >= 0 && nLeft >= 0){ld = IndexOfNote(nPos);int iCom = item.ToLower().CompareTo(ld.Data.ToLower());if (iCom < 0){if (nRight == nLeft || nPos == nLeft){return false;}nRight = nPos - 1;}else if (iCom > 0){if (nRight == nLeft || nPos == nRight){return false;}nLeft = nPos + 1;}else{return true;}nPos = nLeft + (nRight - nLeft + 1) / 2;}}return false;}}#endregion/// <summary>/// 历史记录,相当于栈/// </summary>/// <typeparam name="T"></typeparam>/// 创建时间:2022-03-06    最后一次修改时间:2022-04-19public class UniqueStack_<T>  {private DList_<T> m_List;private int m_Capacity;public DList_<T> List => m_List;/// <summary>/// 元素容量/// </summary>public int Capacity => m_Capacity;/// <summary>/// 无素个数/// </summary>public int Count => m_List.Count;public UniqueStack_(int nCapacity = 15){if(nCapacity <= 0){lg.ShowError("容量不能小于等于 0 !");m_Capacity = 15;}else{ m_Capacity = nCapacity;}m_List = new DList_<T>();}/// <summary>/// 添加一项/// </summary>/// <param name="item"></param>/// 创建时间: 2022-04-19      最后一次修改时间:2022-04-19public void Push(T item){ bool bFind = m_List.RemoveItem(item);  //如果找到,则删除if (!bFind){if (m_List.Count < m_Capacity){m_List.StackPush(item);}else{//插入一个Item,所有元素后移一位m_List.StackPush(item,true);}}else{ //插入一个Item,所有元素后移一位m_List.StackPush(item);                 }            }/// <summary>/// 出栈/// </summary>public void Pop() => List.StackPop();} public class HistoryStringList_ : UniqueStack_<string>{public override string ToString(){string sResult = "";foreach (string s in List){sResult += s + "||";}if (sResult != ""){sResult = sResult.Substring(0, sResult.Length - 2);}return sResult;}public void FromString(string sVaule){List.Clear();StringList_ ls = sVaule._Split("||");DListNote_<string> dnNote = ls.Last;while (dnNote != null){             Push(dnNote.Data);                dnNote = dnNote.Prev;}}public HistoryStringList_(int nCapacity = 15) : base(nCapacity) { }}public class HistoryStringListPair_ : UniqueStack_<Pair_<string, string>>{public override string ToString(){string sResult = "";foreach (Pair_<string, string> pair in List){sResult += pair.First + "," + pair.Second + "||";}if (sResult != ""){sResult = sResult.Substring(0, sResult.Length - 2);}return sResult;}public void FromString(string sVaule){List.Clear();StringList_ ls1 = sVaule._Split("||");DListNote_<string> dnNote = ls1.Last;while (dnNote != null){StringList_ ls2 = dnNote.Data._Split(",");if (ls2.Count == 2){Push(ls2[0], ls2[1]);}dnNote = dnNote.Prev;}}public HistoryStringListPair_(int nCapacity = 15) : base(nCapacity) { }public void Push(string s1, string s2) { base.Push(new Pair_<string, string>(s1, s2)); }public Pair_<string, string> IndexOfFirst(string sFirst){foreach (Pair_<string, string> pair in List){if (pair.First == sFirst)return pair;}return null;}public Pair_<string, string> IndexOfSecond(string sSecond){foreach(Pair_<string, string> pair in List){if(pair.Second == sSecond)return pair;}return null;}}public class LPairList<T1, T2> : IEnumerable{DList_<Pair_<T1, T2>> m_list;public DList_<Pair_<T1, T2>> List { get { return m_list; } }public LPairList(){m_list = new DList_<Pair_<T1, T2>>();}public Pair_<T1, T2> GetIndex(int iIndex){DListNote_<Pair_<T1, T2>> dn = m_list.IndexOfNote(iIndex);if (dn == null)return null;elsereturn dn.Data;}public void RemoveAt(int iIndex){m_list.RemoveAt(iIndex);}public void Clear(){m_list.Clear();}public void Add(T1 First, T2 Second){m_list.Add(new Pair_<T1, T2>(First, Second));}public void Add(Pair_<T1, T2> p){m_list.Add(p);}public void CopyTo(IList il1, IList il2){il1.Clear();il2.Clear();foreach (DListNote_<Pair_<T1, T2>> dn in m_list){il1.Add(dn.Data.First);il2.Add(dn.Data.First);}}public int Count { get { return m_list.Count; } }/// <summary>      /// 创建时间: ????-??-??      最后一次修改时间:2020-05-31/// 查找sFirstStringValue,找不到返回NULL/// </summary>/// <param name="sFirst"></param>/// <returns></returns>public Pair_<T1, T2> IndexFirst(T1 sFirstStringValue){foreach (Pair_<T1, T2> p in m_list){if (p.First.Equals(sFirstStringValue))return p;}return null;}/// <summary>/// 创建时间: ????-??-??      最后一次修改时间:2020-05-31/// 查找sSecondStringValue,找不到返回NULL/// </summary>/// <param name="sFirst"></param>/// <returns></returns>public Pair_<T1, T2> IndexSecond(T2 sSecondStringValue){foreach (Pair_<T1, T2> p in m_list){if (p.Second.Equals(sSecondStringValue))return p;}return null;}/// <summary>/// 创建时间: 2020-05-31      最后一次修改时间:2020-05-31/// 查找第一项,找到返回第二项的值,没找到返回第二项的默认值。/// </summary>/// <param name="sFirstStringValue"></param>/// <returns></returns>public T2 IndexFirstValue(T1 sFirstStringValue){foreach (Pair_<T1, T2> p in m_list){if (p.First.Equals(sFirstStringValue))return p.Second;}return default(T2);}/// <summary>/// 创建时间: 2020-05-31      最后一次修改时间:2020-05-31/// 查找第三项,找到返回第一项的值,没找到返回第一项的默认值。/// </summary>/// <param name="sSecondStringValue"></param>/// <returns></returns>public T1 IndexSecondValue(T2 sSecondStringValue){foreach (Pair_<T1, T2> p in m_list){if (p.Second.Equals(sSecondStringValue))return p.First;}return default(T1);}IEnumerator IEnumerable.GetEnumerator(){return m_list.GetEnumerator();}}public class LStringPairList : LPairList<string, string>{/// <summary>/// 依据slFirst查找Second/// </summary>/// <param name="slFirst"></param>/// 创建时间:2020-05-09   最后一次修改时间:2020-05-09  /// <returns></returns>public StringList_ GetSecondList(StringList_ slFirst){StringList_ slResult = new StringList_();foreach (Pair_<string, string> p in this){if (slFirst.FindNoteItem(p.First) != null){slResult.Add(p.Second);}}return slResult;}/// <summary>/// 依据slSecond查找First/// </summary>/// <param name="slSecond"></param>/// 创建时间:2020-05-09   最后一次修改时间:2020-05-09  /// <returns></returns>public StringList_ GetFirstList(StringList_ slSecond){StringList_ slResult = new StringList_();foreach (Pair_<string, string> p in this){if (slSecond.FindNoteItem(p.Second) != null){slResult.Add(p.First);}}return slResult;}}}

3. Java 版

/***************************************************************************************************创建时间            :   2020年01月12日文件名:             :   LDList.java作者                :   李锋Email              :   ruizhilf@139.com联系电话            :   13828778863作用               :   双向链表此文件暂时以 C# 编程风格,因为 C#也有一份代码,是从C#移植过来的。----------------------------------------------------------------------最后一次修改时间: 2022年07月02日**************************************************************************************************/package JavaPlatform.System;import java.util.ArrayList;
import java.util.Iterator;
import JavaPlatform.jp;class DListNote_<T>
{/*** 节点数据*/public T data;/*** 前一个节点*/public DListNote_<T> prev;/*** 下一个节点*/public DListNote_<T> next;/*** 功能:定位节点指针。** @param nMove 指针移动的个数,0为不变,负数是向上prev方法移动,正数是向下next移动。* @return 返回指向节点的指针  ,移动超出范围返回值为null。 * 创建时间:2022/07/02 最后一次修改时间:2022/07/02*/public DListNote_<T> pointerTo(int nMove){if ( nMove >= 0){   //向下int n = 0;DListNote_<T> pTemp = this;			//计数while(pTemp != null){	    				if( n ==  nMove) break;				pTemp = pTemp.next;	++ n;  }    					return pTemp;			}else{  //向上int n = 0;DListNote_<T> pTemp = this;			//计数while(pTemp != null){	    				if( n == - nMove ) break;				pTemp = pTemp.prev;	++ n;  }    					return pTemp;	   }   }public DListNote_(T adata) {data = adata;}
}/*** The type D list.** @param <T> the type parameter*/
public class DList_<T extends Comparable<T>> implements Iterable<T>{/*** 排序方式*/public enum Sortord_{s_min_max,   //从小到大s_max_min,   //从大到小s_null       //无排序顺序}protected DListNote_<T>  _first;			 //第一个节点protected DListNote_<T>  _last;			    //最后一个节点protected int  _count;			            //节点个数protected Sortord_ _sortord;                //排序顺序/*** 适用于 foreach 语句* @return*/public Iterator<T> iterator() {/*return new Iterator() {private int m_cursor = -1;@Overridepublic T next() {++m_cursor;return indexOfNote(m_cursor).data;}@Overridepublic boolean hasNext() {return m_cursor + 1 < _count;}};*/return new DListNoteEnum_<T>(_first);}private void initData(){_count = 0;_first = null;_last = null;_sortord = Sortord_.s_null;}/*** Instantiates a new D list.*//// <summary>/// 构造函数/// </summary>public DList_() { initData();  }@SafeVarargspublic DList_(T... args){initData();for( T t: args){ add(t); }}/*** Get first d list note.** @return the d list note*/public DListNote_<T> getFirst(){ return _first; }/*** Get last d list note.** @return the d list note*/public DListNote_<T>  getLast(){ return _last; }/*** Get sortord sortord.** @return the sortord*/public Sortord_ getSortord(){ return _sortord; }/*** Get count int.** @return the int*/
/// <summary>/// 实际包含的元素数/// </summary>public int getCount(){return _count;}/*** Add boolean.** @param item the item* @return the boolean*/
/// <summary>/// 将指定集合的元素添加到末尾/// </summary>/// <param name="item">要添加到的末尾处的对象。对于引用类型,该值可以为 null</param>/// <returns>如成功,返回真,否则返回假</returns>public Boolean add(T item){if (_count == 0){_first = new DListNote_<T>(item);_first.next = null;_first.prev = null;_last = _first;}else{DListNote_ pNew = new DListNote_<T>(item);pNew.next = null;pNew.prev = _last;_last.next = pNew;_last = pNew;}++_count;return true;}/*** Add.** @param dList the d list*/public void  add(DList_<T> dList){if (dList == null){throw new NullPointerException();}DListNote_<T> ld = dList._first;while (ld != null){add(ld.data);ld =  ld.next;}}/*** Index of note d list note.** @param iPos the pos* @return the d list note*/
/// <summary>/// 返回索引的节点,从零开始/// </summary>/// <param name="nPos"></param>/// <returns></returns>public  DListNote_<T> indexOfNote(int iPos){if (iPos >= _count || iPos < 0) throw new IndexOutOfBoundsException();int nindex = 0;if (iPos > _count / 2){DListNote_<T> pNote = _last;while (pNote != null){if (nindex++ == _count - iPos - 1){ return pNote;}pNote = pNote.prev;}}else{DListNote_<T> pNote = _first;while (pNote != null){if (nindex++ == iPos){return pNote;}pNote = pNote.next;}}return null;}/*** Bnary search int.** @param item the item* @return the int*/
/// <summary>/// 使用指定的比较器在整个已排序的 中搜索元素,并返回该元素从零开始的索引/// </summary>/// <param name="item">要定位的对象。对于引用类型,该值可以为 null。</param>/// <returns>如果找到 item,则为已排序的  的从零开始的索引;否则为-1; </returns>public  int bnarySearch(T item){switch (_sortord){case s_max_min:{if (_count == 0){return -1;}if (_count == 1){return _first.data.compareTo(item) == 0 ? 0 : -1;}if (_count == 2){if( _first.data.compareTo(item) == 0) return 0;if ( _first.next.data.compareTo(item) == 0) return 1;return -1;}int nPos = _count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = _count - 1;  //右边远素DListNote_<T> ld;while (nRight >= 0 && nLeft >= 0){ld = indexOfNote(nPos);int iCom = item.compareTo(ld.data);if (iCom > 0){if (nRight == nLeft || nPos == nLeft){return -1;}nRight = nPos - 1;}else if (iCom < 0){if (nRight == nLeft || nPos == nRight){return -1;}nLeft = nPos + 1;}else{return nPos;}nPos = nLeft + (nRight - nLeft + 1) / 2;}break;}case s_min_max:{if (_count == 0){return -1;}if (_count == 1){return _first.data.compareTo(item) == 0 ? 0 : -1;}if (_count == 2){if (_first.data.compareTo(item) == 0) return 0;if (_first.next.data.compareTo(item) == 0) return 1;return -1;}int nPos = (int)_count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = (int)_count - 1;  //右边远素DListNote_<T> ld = null;while (nRight >= 0 && nLeft >= 0){ld = indexOfNote(nPos);int iCom = item.compareTo(ld.data);if (iCom < 0){if (nRight == nLeft || nPos == nLeft){return -1;}nRight = nPos - 1;}else if (iCom > 0){if (nRight == nLeft || nPos == nRight){return -1;}nLeft = nPos + 1;}else{return nPos;}nPos = nLeft + (nRight - nLeft + 1) / 2;}break;}case s_null:{DListNote_<T> pNote = _first;int iCount = 0;while (pNote != null){if (pNote.data.equals(item)){return iCount;}pNote = pNote.next;++iCount;}break;}default:{return -1;}}return -1;}/*** Contains boolean.** @param item the item* @return the boolean*/
/// <summary>/// 确定某元素是否在列表中/// </summary>/// <param name="item">查找的对象。对于引用类型,该值可以为 null。</param>/// <returns>如果在列表中找到 item,则为 true,否则为 false。</returns>public  boolean contains(T item){return bnarySearch(item) != -1;}/*** Copy from.** @param ld the ld*/
/// <summary>/// 复制一个链表,清除原来链表的数据/// </summary>/// <param name="ld"></param>public void copyFrom(DList_<T> ld){if (!this.equals(ld)){clear();DListNote_<T> ldItem = ld._first;while (ldItem != null){add(ldItem.data);ldItem = ldItem.next;}}}/*/// <summary>/// 转换成数组/// </summary>/// <returns></returns>public T[] toArray(){T[]  aResult = new T[_count]; //错误: 创建泛型数组int n = 0;DListNote_ pNoteTemp = _first;while (pNoteTemp != null){aResult[n++] = pNoteTemp.data;pNoteTemp = pNoteTemp.next;}return aResult;}*//*** Swap notedata boolean.** @param iIndex1 the index 1* @param iIndex2 the index 2* @return the boolean*/
/// <summary>/// 交换两个节点的数据/// </summary>/// <param name="nIndex1"></param>/// <param name="nIndex2"></param>/// <returns></returns>public   boolean swapNotedata(int iIndex1, int iIndex2){DListNote_<T> pNote1, pNote2;pNote1 = indexOfNote(iIndex1);pNote2 = indexOfNote(iIndex2);if (!(pNote1 != null && pNote2 != null)){return false;}T pTmp = pNote1.data;pNote1.data = pNote2.data;pNote2.data = pTmp;return true;}/*** Sort selection.** @param sortord the sortord*/
/// <summary>/// 选择排序可以说是最简单的一种排序方法:/// 1.找到数组中最小的那个元素/// 2.将最小的这个元素和数组中第一个元素交换位置/// 3.在剩下的元素中找到最小的的元素,与数组第二个元素交换位置/// 重复以上步骤,即可以得到有序数组。/// </summary>public void sort_selection(Sortord_ sortord){_sortord = sortord;  //已排序if (_count == 0 || _count == 1) return;DListNote_<T> min = _first, tmp = _first.next;if (sortord == Sortord_.s_min_max){while (min.next != null){while (tmp != null){if ( tmp.data.compareTo(min.data) < 0)  //交换位置{T pt = tmp.data;tmp.data = min.data;min.data = pt;}tmp = tmp.next;}min = min.next;tmp = min.next;}}else{while (min.next != null){while (tmp != null){if (tmp.data.compareTo(min.data) > 0){T pt = tmp.data;tmp.data = min.data;min.data = pt;}tmp = tmp.next;}min = min.next;tmp = min.next;}}}/*** Inser note front d list note.** @param pListItem the p list item* @param pData     the p data* @return the d list note*/
/// <summary>/// 在结点pListItem前面插入一个结点,成功,返回新的结点,否则返回0/// </summary>/// <param name="pListItem"></param>/// <param name="pData"></param>/// <returns></returns>protected  DListNote_ InserNoteFront(DListNote_ pListItem, T pData){if (pListItem == null){throw new NullPointerException();}DListNote_ pNote = new DListNote_(pData);//pNotepNote.next = pListItem;pNote.prev = pListItem.prev;//--pListItem->previf (pListItem.prev != null){pListItem.prev.next = pNote;}else{_first = pNote;}//pListItempListItem.prev = pNote;++_count;return pNote;}/*** Inser note back d list note.** @param pListItem the p list item* @param pData     the p data* @return the d list note*/
/// <summary>/// 在结点pListItem后面插入一个结点,成功,返回新的结点,否则返回0;/// </summary>/// <param name="pListItem"></param>/// <param name="pData"></param>/// <returns></returns>protected  DListNote_ InserNoteBack(DListNote_ pListItem, T pData){if (pListItem == null) return null;DListNote_ pNote = new DListNote_(pData);//pNotepNote.prev = pListItem;pNote.next = pListItem.next;//pListItem->nextif (pListItem.next != null){pListItem.next.prev = pNote;}else{_last = pNote;}//--pListItempListItem.next = pNote;++_count;return pNote;}/*** Find note item d list note.** @param item the item* @return the d list note*/
/// <summary>/// 找查一个项,而不是节点,返回的这个节点相当于指针。/// </summary>/// <param name="pData">项值</param>/// <returns></returns>public  DListNote_ findNoteItem(T item){switch (_sortord){case s_max_min:{if (_count == 0){return null;}if (_count == 1){return _first.data.compareTo(item) == 0 ? _first : null;}if (_count == 2){if (_first.data.compareTo(item) == 0) return _first;if (_first.next.data.compareTo(item) == 0) return _first.next;return null;}int nPos = _count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = _count - 1;  //右边远素DListNote_<T> ld = null;while (nRight >= 0 && nLeft >= 0){ld = indexOfNote(nPos);int iCom = item.compareTo(ld.data);if (iCom > 0){if (nRight == nLeft || nPos == nLeft){return null;}nRight = nPos - 1;}else if (iCom < 0){if (nRight == nLeft || nPos == nRight){return null;}nLeft = nPos + 1;}else{return ld;}nPos = nLeft + (nRight - nLeft + 1) / 2;}break;}case s_min_max:{if (_count == 0){return null;}if (_count == 1){return _first.data.compareTo(item) == 0 ? _first : null;}if (_count == 2){if (_first.data.compareTo(item) == 0) return _first;if (_first.next.data.compareTo(item) == 0) return _first.next;return null;}int nPos = _count / 2;   //nPos在中间,所以无素一定要大于等于3才行int nLeft = 0;   //左边远素int nRight = _count - 1;  //右边远素DListNote_<T> ld = null;while (nRight >= 0 && nLeft >= 0){ld = indexOfNote(nPos);int iCom = item.compareTo(ld.data);if (iCom < 0){if (nRight == nLeft || nPos == nLeft){return null;}nRight = nPos - 1;}else if (iCom > 0){if (nRight == nLeft || nPos == nRight){return null;}nLeft = nPos + 1;}else{return ld;}nPos = nLeft + (nRight - nLeft + 1) / 2;}break;}case s_null:{DListNote_<T> pNote = _first;while (pNote != null){//总结:Equals比较的永远是变量的内容是否相同,而= =比较的则是引用地址是否相同(前提:此种类型内部没有对Equals 或= = 进行重写操作,//否则输出可能会有不同)。string 类型是个特例,因为他的内部对这两个都进行了重写。if (item.compareTo(pNote.data) == 0){return pNote;}/*if (pNote.data.Equals(item)){return pNote;}*/pNote = pNote.next;}break;}default:{return null;}}return null;}/*** Move last boolean.** @param iIndex the index* @return the boolean*/
/// <summary>/// 把索引为nIndex的节点移到最后/// </summary>/// <param name="nIndex"></param>/// <returns></returns>protected boolean moveLast(int iIndex){DListNote_ pNote = indexOfNote(iIndex);if (pNote != null){if (pNote == _last)return true;if (pNote == _first) //此时最少两个节点{_first = _first.next;_first.prev = null;_last.next = pNote;pNote.prev = _last;_last = pNote;}else{pNote.prev.next = pNote.next;pNote.next.prev = pNote.prev;_last.next = pNote;pNote.prev = _last;_last = pNote;}return true;}return false;}/*** Move first boolean.** @param iIndex the index* @return the boolean*/
/// <summary>/// 把索引为nIndex的节点移到最前/// </summary>/// <param name="nIndex"></param>/// <returns></returns>protected boolean moveFirst(int iIndex){DListNote_ pNote = indexOfNote(iIndex);if (pNote != null){if (pNote == _first)return true;if (pNote == _last)  //此时最少两个节点{_last.prev.next = null;_last = _last.prev;pNote.prev = null;pNote.next = _first;_first.prev = pNote;_first = pNote;}else{pNote.prev.next = pNote.next;pNote.next.prev = pNote.prev;pNote.next = _first;_first.prev = pNote;pNote.prev = null;_first = pNote;}return true;}return false;}/*** Remove item boolean.** @param pData the p data* @return the boolean*/
/// <summary>/// 删除链表中的数据/// </summary>/// <param name="pData"></param>/// <returns></returns>public  boolean  RemoveItem(T pData){if (_sortord == Sortord_.s_null){DListNote_ pListItem = _first;while (pListItem != null){if (pListItem.data.equals(pData))	//找到一项{if (pListItem == _first)		//删除的是第一个节点{if (_first.next != null){_first.next.prev = null;_first = _first.next;}else{_first = null;_last = null;}}else if (pListItem == _last)  //删除的是最后一个节点{if (_last.prev != null){_last.prev.next = null;_last = _last.prev;}else{_first = null;_last = null;}}else						//删除的是中间的一个节点{pListItem.next.prev = pListItem.prev;pListItem.prev.next = pListItem.next;}--_count;return true;}pListItem = pListItem.next;}return false;}else{return removeAt(bnarySearch(pData));}}/*** Delete node boolean.** @param pListItem the p list item* @return the boolean*/
/// <summary>/// 删除链表中的节点/// </summary>/// <param name="pListItem"></param>/// <returns></returns>protected boolean deleteNode(DListNote_ pListItem){if (_count == 0 || pListItem == null){return false;}DListNote_ pNote = _first.next;while (pNote != null){if (pNote == pListItem)  //找到了{//pListItem->previf (pListItem.prev != null){pListItem.prev.next = pListItem.next;}else //删除的是第一个节点{_first = pListItem.next;}//pListItem->nextif (pListItem.next != null){pListItem.next.prev = pListItem.prev;}else //删除的是最后一个节点{_last = pListItem.prev;}break;}pNote = pNote.next;}if (pNote != null){--_count;return true;}return false;}/*** 功能:清空所有元素的所有数据,并清空链表* 创建时间:????/??/??* 最后一次修改时间:2022-07-02*/public void clear(){_count = 0;DListNote_ pTemp1 = _first;while (pTemp1 != null){DListNote_ pTemp2 = pTemp1.next;pTemp1.data = null;pTemp1.next = null;pTemp1.prev = null;pTemp1 = pTemp2;}_first = null;_last = null;}/*** Remove at boolean.** @param iIndex the index* @return the boolean*/
/// <summary>/// 移除指定索引处的元素/// </summary>/// <param name="iIndex">要移除的元素的从零开始的索引。</param>/// <returns>成功返回true,否则返回false</returns>public Boolean removeAt(int iIndex){if (iIndex < 0 || iIndex + 1 > _count) { return false; }DListNote_ pNode = _first;int iCount = 0;while (pNode != null){if (iCount == iIndex){if (pNode == _first){if (_first.next == null)   //只有一个{clear();return true;}else{_first = _first.next;_first.prev = null;--_count;return true;}}else if (pNode == _last){if (_last.prev == null){clear();return true;}else{_last = _last.prev;_last.next = null;--_count;return true;}}else{pNode.prev.next = pNode.next;pNode.next.prev = pNode.prev;pNode = null;--_count;return true;}}pNode = pNode.next;++iCount;}return false;}/*** Printlf.*/public void printlf(){jp.p(toString()); }/*** 功能:删除一段链表,注意:pDeleteNoteStart 一定要在链表内。** @param pDeleteNoteStart 开始删除的位置* @param bDown            删除方向,向下还是向上,prev 为向上,next 为向上* @param nCount           要删除的个数,包括 pDeleteNoteStart* @return 返回实际删除的个数   作者:李锋 创建时间:2022/07/02 最后一次修改时间:2022/07/02*/public int removeNotes(DListNote_ pDeleteNoteStart,boolean bDown,int nCount){if(_count <= 0 || nCount <= 0 || pDeleteNoteStart == null ) return 0;    	if(pDeleteNoteStart == _first){         //如果删除的开始位置是链表中的第一个节点if( bDown ){  //向下int n = 0;DListNote_ pTemp = _first;        			//计数while(pTemp != null){ 	++ n;   pTemp.data = null;pTemp = pTemp.next;    if( n ==  nCount) break;   	    		    	} 			   if(pTemp == null){    clear();    	return _count;}else {    	//重新设置 _firstpTemp.prev = null;_first = pTemp;_count -= nCount;   return nCount;}  	    			} else{  //向上,只删除一个,重新设置 _firstif(_count == 1){clear();}else{		-- _count;_first.data = null;DListNote_ pTemp = _first.next;pTemp.prev = null;_first = pTemp;}return 1;}	}else if(pDeleteNoteStart == _last){  //如果删除的开始位置是链表中的最后一个节点   	if( bDown ){  //向下,只删除一个,重新设置 _lastif(_count == 1){clear();}else{-- _count;_last.data = null;DListNote_ pTemp = _last.prev;pTemp.next = null;_last = pTemp;}return 1;} else{  //向上int n = 0;DListNote_ pTemp = _last;        			//计数while(pTemp != null){ 	++ n;   pTemp.data = null;pTemp = pTemp.prev;    if( n ==  nCount) break;}if(pTemp == null){clear();return _count;}else {    	//重新设置 _lastpTemp.next = null;_last = pTemp;_count -= nCount;   return nCount;}}	  		}else{if( bDown ){  			 int n = 0;DListNote_ pTemp = pDeleteNoteStart;        			//计数while(pTemp != null){ 	++ n;   pTemp.data = null;pTemp = pTemp.next;  if( n ==  nCount) break;    				      		  }if(pTemp == null)  //_last也删掉了{  				 pDeleteNoteStart.prev.next = null;_last = pDeleteNoteStart.prev;    				 _count -= n;   return n;   //实际删除个数}else {   	    				pDeleteNoteStart.prev.next = pTemp;pTemp.prev = pDeleteNoteStart.prev;    			 _count -= nCount;   return nCount;}    			} else{int n = 0;DListNote_ pTemp = pDeleteNoteStart;        			//计数while(pTemp != null){ 	++ n;   pTemp.data = null;pTemp = pTemp.prev;    if( n ==  nCount) break;}if(pTemp == null) { //_first 也删掉了pDeleteNoteStart.next.prev = null;    				_first = pDeleteNoteStart.next;_count -= n;   			return n;   //实际删除个数}else {   	pTemp.next = pDeleteNoteStart.next;pDeleteNoteStart.next.prev = pTemp;        			 _count -= nCount;   return nCount;}    	  }}  	  	    }/*** 添加一个元素,并把它放在首位,其它元素后移,如果后面的元素删除,总无素个数不变,如果无素个数为零,则添加一个无素。** @param Item        the item* @param bRemoveLast 创建时间: 2022-04-19      最后一次修改时间:2022-04-19*/public void stackPush(T Item, boolean bRemoveLast){if (_count == 0){add(Item);}else if (_count == 1){if (bRemoveLast){_first.data = Item;}else{//把无素放在最前DListNote_ dnNew = new DListNote_(Item);_first.prev = dnNew;dnNew.next = _first;_first = dnNew;++_count;}}else{if (bRemoveLast){//删除最后一个元素_last = _last.prev;_last.next = null;//把无素放在最前DListNote_ dnNew = new DListNote_(Item);_first.prev = dnNew;dnNew.next = _first;dnNew.prev = null;_first = dnNew;}else {//把无素放在最前DListNote_ dnNew = new DListNote_(Item);_first.prev = dnNew;dnNew.next = _first;dnNew.prev = null;_first = dnNew;++_count;}}}/*** Stack pop.*/
/// <summary>/// 删除第一个元素,出栈/// </summary>/// 创建时间: 2022-04-19      最后一次修改时间:2022-04-19public void stackPop(){ removeAt(0); }/*** To array list array list.** @return the array list*/public ArrayList<T> toArrayList(){ArrayList<T> la = new ArrayList<T>();for(T value : this){la.add(value); }return la;}/*** 功能: 转为字符串格式  类名:{ a 分隔符 b 分隔符 c }** @param separator 分隔符* @return string* @author 李锋* @since 创建日期 :2022-08-08,最后一次修改日期:2022-08-08*/public String toString(String  sConnector){String info = this.getClass() + " :\t";//info += "{";int i = 0;for ( T  t : this) {info += t.toString();++ i ;if( i != _count)info +=  sConnector;}//info += "}";return info;}/*** 功能: 转为字符串格式  类名:{ a , b , c }* @return* @since 创建日期:2022-08-08,最后一次修改日期:2022-08-08* @author 李锋*/@Overridepublic String toString() {return  toString(",");}}class DListNoteEnum_<T> implements Iterator<T> {private DListNote_<T> _dnCurr;private int _index = -1;public DListNoteEnum_(DListNote_<T> dn){_dnCurr = dn;}@Overridepublic boolean hasNext() {return _dnCurr.next != null;}@Overridepublic T next() {   ++ _index;if( _index > 0){_dnCurr = _dnCurr.next;}        return _dnCurr.data; }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/330368.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

重学java 40.多线程 — 死锁和线程状态

—— 24.5. 一、死锁 1.死锁介绍&#xff08;锁嵌套就有可能产生死锁&#xff09; 指的是两个或者两个以上的线程在执行的过程中由于竞争同步锁而产生的一种阻塞现象;如果没有外力的作用,他们将无法继续执行下去,这种情况称之为死锁 例&#xff1a; 两线程处于互相等待的状态&a…

nss刷题(3)

1、[SWPUCTF 2021 新生赛]include 根据提示传入一个file后显示了关于flag的代码 这是一个文件包含&#xff0c;考虑php伪协议&#xff0c;构造payload&#xff1a; ?filephp://filter/readconvert.base64-encode/resourceflag.php 2、[SWPUCTF 2021 新生赛]Do_you_know_http …

MyBatisPlus使用流程

引入依赖 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.4</version> </dependency> 版本号根据需要选取 在实体类上加注解声明&#xff0c;表信息 根据数…

go-zero 实战(5)

引入Prometheus 用 Prometheus 监控应用 1. 用 docker 启动 Prometheus 编辑配置位置&#xff0c;我将 prometheus.yaml 和 targets.json 文件放在了 /opt/prometheus/conf目录下 prometheus.yaml global:scrape_interval: 15s # 抓取间隔evaluation_interval: 15s # 评估…

网络拓扑—DHCP服务配置

文章目录 DHCP服务搭建相关配置细节前提安装DHCP服务 DHCP服务搭建 相关配置细节前提 系统&#xff1a;Windows Server 2003 IP网段&#xff1a;10.0.0.0/24 三台机子&#xff1a; 普通PC机 DHCP服务器 路由器&#xff08;两块网卡&#xff0c;连接内外网&#xff09; //注…

中国主要城市房价指数数据集(2011-2024)

数据来源&#xff1a;东方财富网 时间跨度&#xff1a;2011年1月 - 2024年4月 数据范围&#xff1a;中国主要城市 包含指标&#xff1a; 日期、城市 新建商品住宅价格指数-同比 新建商品住宅价格指数-环比 新建商品住宅价格指数-定基 二手住宅价格指数-环比 二手住宅价格指…

get和post的区别,二者是幂等的吗?

一、什么是幂等 所谓幂等性通俗的将就是一次请求和多次请求同一个资源产生相同的副作用。 维基百科定义&#xff1a;幂等&#xff08;idempotent、idempotence&#xff09;是一个数学与计算机学概念&#xff0c;常见于抽象代数中。 在编程中一个幂等操作的特点是其任意多次执…

Docker(四) 文件和网络

1 Dockerfile 1.1 什么是Dockerfile Dockerfile是一个文本文件&#xff0c;包含一系列命令&#xff0c;这些命令用于在 Docker 镜像中自动执行操作。Dockerfile 定义了如何构建 Docker 镜像的步骤和所需的操作。 Dockerfile 中包含的命令可以设置和定制容器的环境&#xff0c;…

优于InstantID!中山大学提出ConsistentID:可以仅使用单个图像根据文本提示生成不同的个性化ID图像

给定一些输入ID的图像&#xff0c;ConsistentID可以仅使用单个图像根据文本提示生成不同的个性化ID图像。效果看起来也是非常不错。 相关链接 Code:https://github.com/JackAILab/ConsistentID Paper&#xff1a;https://ssugarwh.github.io/consistentid.github.io/arXiv.pd…

一文带你入门ini格式

引入: 以蜂鸣器为例&#xff0c;每次我们增加新的设备&#xff0c; 都需要添加两个新文件: 修改程序代码&#xff0c;手动添加: 缺点: 不利于维护 设备类节点直接通过ini文件配置 什么是.ini文件 ini文件通常以纯文本形式存在&#xff0c;并且包含了一个或多个节&#xff08;se…

java技术:spring-secrity实现认证、授权

目录 一、依赖 二、逻辑图 三、代码设计 1、WebSecurityConfigurerAdapter的实现类 2、设计登录接口 config配置&#xff1a; 1&#xff09;UserDetailsService实现类重写&#xff1a; 2&#xff09;书写登录实现类&#xff08;调用authenticationManager、可以与后面的…

重新夺回控制权!原创始人从Synk回购FossID,致力于解决开源许可合规风险

FossID 于 2022 年 9 月被其原始创始人从 Snyk, Inc. 重新收购。为什么 Snyk 在 2021 年收购了 FossID&#xff0c;又在 2022 年将其分拆&#xff0c;以及为什么 FossID 的创始人&#xff08;Oskar Swirtun 和 Jon Aldama&#xff09;后来又回购了该公司&#xff1f; 公司背景 …

类和对象的基本概念

类和对象的基本概念 C和C中struct区别类的封装封装访问权限总结struct和class的区别 将成员变量设置为private C和C中struct区别 C语言struct只有变量C语言struct 既有变量&#xff0c;也有函数 类的封装 封装 把变量&#xff08;属性&#xff09;和函数&#xff08;操作&a…

Undet for SketchUp 2023.3 点云建模软件 支持支持草图大师sketchup2021-2022-2023

1.Undet for sketchup 2023.3支持草图大师sketchup2021-2022-2023。支持机载雷达扫描、车载扫描还是地面扫描&#xff0c;对AEC行业用户来说&#xff0c;真正需要的是如何将这些数据快速处理为三维模型&#xff0c;这样才能将这些信息延展到BIM领域发挥效用。因此面对这些海量的…

Go源码--sync库(1)sync.Once和

简介 这篇主要介绍 sync.Once、sync.WaitGroup和sync.Mutex sync.Once once 顾名思义 只执行一次 废话不说 我们看源码 英文介绍直接略过了 感兴趣的建议读一读 获益匪浅 其结构体如下 Once 是一个严格只执行一次的object type Once struct {// 建议看下源码的注解&#xf…

python:pycharm虚拟解释器报错环境位置目录为空

目录 解释器分控制台解释器 和 pycharm解释器 控制台解释器切换&#xff1a; pycharm解释器 解释器分控制台解释器 和 pycharm解释器 控制台解释器切换&#xff1a; 切换到解释器下 激活解释器 查看解释器 where python 激活成功 这时在控制台使用python xxx.py 可以…

表现层框架设计之表现层设计模式_3.MVVM模式

1.MVVM模式 MVVM模式正是为解决MVP中UI种类变多&#xff0c;接口也会不断增加的问题而提出的。 MVVM模式全称是模型-视图-视图模型&#xff08;Model-View-ViewModel&#xff09;&#xff0c;它和MVC、MVP类似&#xff0c;主要目的都是为了实现视图和模型的分离&#xff0c;不…

Flink 生态对 Confluent / Kafka Schema Registry 支持情况的研究报告

文章目录 1. Flink CDC 对 Confluent Schema Registry 的支持情况2. Confluent Avro Format 对 Confluent Schema Registry 的支持情况3. 关键性结论 这几年&#xff0c;在流式链路上引入一个 Schema Registry 变得越来越流行&#xff0c;也越来越有必要&#xff0c; Schema Re…

信息化项目交付验收流程管理办法

项目交付验收流程制度 管理办法 (执行版) (文件编号: ) 编制: 审核: 批准: 版本: 生效日期: 管理办法概述 制定目的为了保证公司在建项目交付验收工作事项的顺利开展,保证交付验收进度及…