C++标准库双向链表 list 中的insert函数实现。

embedded/2024/10/19 3:35:20/

 C++Primer中文版(第五版):

   //运行时错误:迭代器表示要拷贝的范围,不能指向与目的位置相同的容器
    slist.insert(slist.begin(),slist.begin(),slist.end());
    
如果我们传递给insert一对迭代器,它们不能指向添加元素的目标容器。
       在新标准下,接受元素个数范围的insert版本返回指向第一个新加入元素的迭代
    
器。(在旧版本的标准库存中,这些操作返回void。)如果范围为空,不插入任何元素,insert
操作会将第一个参数返回。
 

例子1:

int main() {list<string> sl1 = { "1","2","3" };_DList<string> sl2 = { "1","2","3" };vector<string> v = { "quasi", "simba","frollo","scar" };//将v的最后两个元素添加到list的开始位置sl1.insert(sl1.begin(), v.end() - 2, v.end());sl2.std_insert(sl2.begin(), v.end() - 2, v.end());_pn(sl1);_pn(sl2);cout << "----------------------------------------------------------\n";//添加一列表sl1.insert(sl1.end(), { "4","5","6","7","中文","8","9" });sl2.std_insert(sl2.end(), { "4","5","6","7","中文","8","9" }); _pn(sl1);_pn(sl2);cout << "----------------------------------------------------------\n";//复制自己(旧版会运行时错误,迭代器表示要拷贝的范围,不能指向与目的位置相同的容器)sl1.insert(sl1.begin(), sl1.begin(), sl1.end());sl2.std_insert(sl2.begin(), sl2.begin(), sl2.end());_pn(sl1);_pn(sl2);}

结果:

例子2:

 
int main() {_DList<string> lst1;list<string> lst2;string word;auto iter1 = lst1.begin();auto iter2 = lst2.begin();while (cin >> word) {iter1 = lst1.std_insert(iter1, word); //等价于调用push_front_pn(lst1);iter2 = lst2.insert(iter2, word); //等价于调用push_front_pn(lst2);}
}

结果:

_DList中的实现:

主要函数:

 /// <summary>/// 在_Where位置前插入[itBegin,itEnd)(用法与std::list::insert要一样)/// 注意:std旧重版itBegin和itEnd不能指向与目的位置相同的容器,在新标准版可以。/// </summary>/// <typeparam name="IteratorClass"></typeparam>/// <param name="_Where"></param>/// <param name="itBegin"></param>/// <param name="itEnd"></param>/// 创建时间: 2024-09-22      最后一次修改时间:2024-09-22 (已测试)template<class IteratorClass>inline _DListNodeIterator<T> std_insert(const _DListNodeIterator<T>& _Where, const IteratorClass& itBegin,const IteratorClass& itEnd) {/*list slist;      //运行时错误:迭代器表示要拷贝的范围,不能指向与目的位置相同的容器slist.insert(slist.begin(),slist.begin(),slist.end());*/if (typeid(_DListNodeIterator<T>) == typeid(IteratorClass)) {_DListNodeIterator<T>* pbegin = (_DListNodeIterator<T>*)(&itBegin);_DListNodeIterator<T>* pend = (_DListNodeIterator<T>*)(&itEnd);//lassert(_Where._pCurrentList != p->_pCurrentList,"不能插入指向相同容器的元素");if (_Where._pCurrentList == pbegin->_pCurrentList) {//创建一个临时链表,会影响性能_DList<T> tmp(*pbegin,*pend);return std_insert(_Where, tmp.begin(), tmp.end());}            }     IteratorClass tmp = itBegin;_DListNode<T>* pReulst = null;if (_Where._Ptr == null) {while (tmp != itEnd) {if (pReulst == null) {//保存第一次插入的结点,以便返回pReulst = this->inseart_back(_Last, *tmp);}elsethis->inseart_back(_Last, *tmp);++tmp;}}else {auto ptr = _Where._Ptr;while (tmp != itEnd) {if (pReulst == null) //第一次,在前面插入第一项{ptr = this->inseart_front(ptr, *tmp);//保存第一次插入的结点,以便返回pReulst = ptr;}else { //第二次开始,在插入的第一项后面依次插入ptr = this->inseart_back(ptr, *tmp);}++tmp;}}return _DListNodeIterator<T>(pReulst, this);}

 _DList类,有修改:

/*******************************************************************************************
文件名			: _List.h作者				: 李锋功能				: 链表手机				: 13828778863Email			:  ruizhilf@139.com创建时间			: 2016年07月31日最后一次修改时间	:  2024年07月30日/// 链表是一种用来存储数据集合的数据结构链表具有如下属性
///(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"
#include "_IteratorBase.h"_LF_BEGIN_template<class T> class _DList; //前置声明/// <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  
{
public:using value_type = T;
public:/// <summary>/// 当前节点/// </summary>_DListNode<T>* _Ptr;   //命名与标库相同  _pCurrentNode;/// <summary>/// 当前链表/// </summary>const _DList<T>*  _pCurrentList;inline _DListNodeIterator(){ _pCurrentList = null;_Ptr = null;}inline _DListNodeIterator(const _DList<T>* pCurrentList){assert(pCurrentList != null);_pCurrentList = (_DList<T>*)pCurrentList;_Ptr = null;}/// <summary>/// 构造函数,传值迭代器管理的值/// </summary>/// <param name="pNode"></param>inline _DListNodeIterator(const _DListNode<T>* pCurrentNode, const  _DList<T>* pCurrentList){_Ptr = (_DListNode<T>*)pCurrentNode;_pCurrentList = (_DList<T>*)pCurrentList;}inline _DListNodeIterator(const _DListNodeIterator& it)   {_Ptr = it._Ptr;_pCurrentList = it._pCurrentList;}/*/// <summary>/// 比较实现/// </summary>/// <param name="that"></param>/// <returns></returns>bool operator != (const _DListNodeIterator& that) { return _pNode != that._pNode; }bool operator > (const _DListNodeIterator& right) { return _pNode->Data > right._pNode->Data; }bool operator < (const _DListNodeIterator& right) { return _pNode->Data < right._pNode->Data; }/// <summary>/// 自增实现/// </summary>/// <returns></returns>inline _DListNodeIterator& operator ++ () { _pNode = _pNode->Next;   return *this; }/// <summary>/// lf::_DList<int> d = { 1,3,5,8,2 };/// auto it1 = d.begin();  /// cout << *it1 << "\n";        // 输出:1/// cout << *(it1 + 2) << "\n";  // 输出:5/// </summary>/// <param name="nDiff"></param>/// <returns></returns>/// 创建时间: 2024-07-01     最后一修改时间:2024-07-01inline _DListNodeIterator operator+(const size_t nDiff) {_DListNodeIterator result(_pNode);   for (int n = 0; n < nDiff; ++n){result._pNode = result._pNode->Next;}return result;}/// <summary>/// 解引用,取值/// </summary>/// <typeparam name="T"></typeparam>T& operator * () { return _pNode->Data; }//LDIterator(const LDIterator&) = delete;//LDIterator& operator=(const LDIterator&) = delete;//~LDIterator() = default;*/public: //----------------------------重写 /// <summary>/// 解引用,取值/// </summary>/// <typeparam name="T"></typeparam>/// 创建时间:2024-07-02    最后一次修改时间:2024-07-03inline T& operator * () const { return _Ptr->Data; }/// <summary>/// 向前移动为正,向后移动为负/// </summary>/// <param name="iDiff"></param>/// 创建时间:2024-07-02    最后一次修改时间:2024-07-02inline virtual void Move(const int& iDiff) {if (iDiff == 0) return;if (iDiff > 0){if (_Ptr == null) //已经是最后了,不能向后移了{ return;}int n = 0;while (true){_Ptr = _Ptr->Next;++n;if (n == iDiff){  return; }}}else{int n = 0;if (_Ptr == null) {//向前移,减-1进入未尾元素_Ptr = _pCurrentList->Last();n = -1;  //已经向前移了一位if (n == iDiff) { return; }}while (true){_Ptr = _Ptr->Prev;--n;if (n == iDiff){ return; }}}throw "未重写代码?";}/// <summary>/// /// </summary>/// <param name="right"></param>/// <returns></returns>/// 创建时间:2024-07-02    最后一次修改时间:2024-07-02inline _DListNodeIterator operator+(const int& iDiff)const {_DListNodeIterator itResult(*this);itResult.Move(iDiff);return itResult;}/// <summary>/// /// </summary>/// <param name="right"></param>/// <returns></returns>/// 创建时间:2024-07-02    最后一次修改时间:2024-07-02inline _DListNodeIterator operator-(const int& iDiff)const {_DListNodeIterator itResult(*this);itResult.Move(-iDiff);return itResult;}/// <summary>/// /// </summary>/// <param name="r"></param>/// <returns></returns>/// 创建时间:2024-07-03    最后一次修改时间:2024-07-25inline int operator-(const _DListNodeIterator& r)const {int n1 = _pCurrentList->FindNodeIndex(_Ptr);int n2 = _pCurrentList->FindNodeIndex(r._Ptr);//assert(n1 != -1 && n2 != -1);//确保 _pCurrentList->end() - _pCurrentList->begin() == _pCurrentList->Count//超过边界,指针都设为指向最后一位元素的下一位if (n1 == -1)  n1 = _pCurrentList->Count;if (n2 == -1)  n2 = _pCurrentList->Count;return n1 - n2; }/// <summary>/// 前置加加/// </summary>/// <returns></returns>/// 创建时间:2024-07-02    最后一次修改时间:2024-07-02inline _DListNodeIterator& operator++() { Move(1); return  *this; }/// <summary>/// 前置减减/// </summary>/// <returns></returns>/// 创建时间:2024-07-02    最后一次修改时间:2024-07-02inline _DListNodeIterator& operator--() { Move(-1); return  *this; }/// <summary>/// 后置加加/// </summary>/// <param name=""></param>/// <returns></returns>/// 创建时间:2024-07-02    最后一次修改时间:2024-07-02inline _DListNodeIterator operator++(int) {_DListNodeIterator sResult(*this);Move(1);return sResult;}/// <summary>/// 后置减减/// </summary>/// <param name=""></param>/// <returns></returns>/// 创建时间:2024-07-02    最后一次修改时间:2024-07-02inline _DListNodeIterator operator--(int) {_DListNodeIterator sResult(*this);Move(-1);return sResult;}/// <summary>/// /// </summary>/// <param name="r"></param>/// <returns></returns>/// 创建时间:2024-07-02    最后一次修改时间:2024-07-02inline _DListNodeIterator& operator+=(const int& iDiff) {Move(iDiff);return *this;}/// <summary>/// /// </summary>/// <param name="r"></param>/// <returns></returns>/// 创建时间:2024-07-02    最后一次修改时间:2024-07-02inline _DListNodeIterator& operator-=(const int& iDiff) {Move(iDiff);return *this;}/// <summary>///  关联代码:///  _DList<int> d = { 1,3,53,55,35,97,35,10 };///  d.end() - d.begin(); //8/// </summary>/// <param name="r"></param>/// <returns></returns>/// 创建时间:2024-07-03    最后一次修改时间:2024-07-03inline int operator-(const _DListNodeIterator& r){//note1 到最未尾的索引//note2 到最未尾的索引int i1 = 0, i2 = 0;auto pNode1 = _Ptr;auto pNode2 = r._Ptr;//pNote1到结点未尾的距离while (pNode1 != null){pNode1 = pNode1->Next;++i1;}//pNote2到结点未尾的距离while (pNode2 != null){pNode2 = pNode2->Next;++i2;}// - (i1-i2)  值越小,离结点未越近,例如 null 结点,就是 0。return  i2 - i1;}//-------------------------------如果是非线性表,下面的运算符重载也要重写inline bool operator!=(const _DListNodeIterator& r) { return this->_Ptr != r._Ptr; }inline bool operator==(const _DListNodeIterator& r) { return this->_Ptr == r._Ptr; }inline bool operator>(const _DListNodeIterator& r) { return this->_Ptr > r._Ptr; }inline bool operator<(const _DListNodeIterator& r) { return this->_Ptr < r._Ptr; }
};/// <summary>
/// 
/// </summary>
/// <typeparam name="T"></typeparam>
/// 创建时间: 2024-07-03     最后一修改时间:2024-07-03
template<class T>
class _DListNodeReverseIterator
{
public:using value_type = T;private:/// <summary>/// 当前节点/// </summary>_DListNode<T>* _pCurrentNode;/// <summary>/// 当前链表/// </summary>_DList<T>* _pCurrentList;
public:inline _DListNodeReverseIterator(){_pCurrentList = null;_pCurrentNode = null;}inline _DListNodeReverseIterator(const _DList<T>* pCurrentList){assert(pCurrentList != null);_pCurrentList = (_DList<T>*)pCurrentList;_pCurrentNode = null; }/// <summary>/// 构造函数,传值迭代器管理的值/// </summary>/// <param name="pNode"></param>inline _DListNodeReverseIterator(const _DListNode<T>* pCurrentNode, const _DList<T>* pCurrentList){_pCurrentNode = (_DListNode<T>*)pCurrentNode;_pCurrentList = (_DList<T>*)pCurrentList;}inline _DListNodeReverseIterator(const _DListNodeReverseIterator& it){_pCurrentNode = it._pCurrentNode;_pCurrentList = it._pCurrentList;}/// <summary>/// 解引用,取值/// </summary>/// <typeparam name="T"></typeparam>/// 创建时间:2024-07-02    最后一次修改时间:2024-07-03inline T& operator * ()const { return _pCurrentNode->Data; }/// <summary>/// 前置加加/// </summary>/// <returns></returns>/// 创建时间:2024-07-02    最后一次修改时间:2024-07-02inline _DListNodeReverseIterator& operator++() { Move(1); return  *this; }/// <summary>/// 前置减减/// </summary>/// <returns></returns>/// 创建时间:2024-07-02    最后一次修改时间:2024-07-02inline _DListNodeReverseIterator& operator--() { Move(-1); return  *this; }/// <summary>/// 后置加加/// </summary>/// <param name=""></param>/// <returns></returns>/// 创建时间:2024-07-02    最后一次修改时间:2024-07-02inline _DListNodeReverseIterator operator++(int) {_DListNodeIterator sResult(*this);Move(1);return sResult;}/// <summary>/// 后置减减/// </summary>/// <param name=""></param>/// <returns></returns>/// 创建时间:2024-07-02    最后一次修改时间:2024-07-02inline _DListNodeReverseIterator operator--(int) {_DListNodeIterator sResult(*this);Move(-1);return sResult;}/// <summary>/// 向后移动为正,向前移动为负/// </summary>/// <param name="iDiff"></param>/// 创建时间:2024-07-02    最后一次修改时间:2024-07-02inline void Move(const int& iDiff) {assert(_pCurrentList != null);if (iDiff == 0) return;if (iDiff > 0) {  //向后移动int n = 0;if (_pCurrentNode == null) {  //不能向前移动_pCurrentNode = _pCurrentList->Last();n = 1;  //已经向后移动了一位 if (n == iDiff) { return; }}while (true) {_pCurrentNode = _pCurrentNode->Prev;++n;if (n == iDiff) { return; }}}else {if (_pCurrentNode == null) {  //不能向后移动return;}int n = 0;while (true) {_pCurrentNode = _pCurrentNode->Next;--n;if (n == iDiff) { return;}}}throw "未重写代码?";}inline bool operator!=(const _DListNodeReverseIterator& r) { return this->_pCurrentNode != r._pCurrentNode; }inline bool operator==(const _DListNodeReverseIterator& r) { return this->_pCurrentNode == r._pCurrentNode; }inline bool operator>(const _DListNodeReverseIterator& r) { return this->_pCurrentNode > r._pCurrentNode; }inline bool operator<(const _DListNodeReverseIterator& r) { return this->_pCurrentNode < r._pCurrentNode; }
};/// <summary>
/// 双向链表,  数据 T 要求能够比较大小,否则编译会出错。
/// </summary>
/// <typeparam name="T"></typeparam>
template<class T>
class _DList : public _Object
{
public:using value_type = T;using iterator = _DListNodeIterator<T>;static const size_t  npos = -1;      //不可能的索引  
protected:_DListNode<T>*  _First;	        //第一个节点_DListNode<T>*  _Last;		    //最后一个节点size_t          _Count;			//节点个数size_t          _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;/// <summary>/// 为了兼容标准库。/// 例:T = vector, string, _DList..../// size_t nSize = T.size();/// auto itBegin = T.begin();/// </summary>/// <returns></returns>/// 创建时间: 2024-07-30     最后一修改时间:2024-07-30int size()const { return _Count; }inline int GetCount() const { return _Count; }public://------------------------------------------------------------构造与析构/// <summary>/// 默认构造函数/// </summary>/// <returns></returns>inline _DList(){InitData();}/// <summary>/// 拷贝[itBegin,itEnd)/// </summary>/// <param name="itBegin"></param>/// <param name="itEnd"></param>/// 创建时间: 2024-09-23     最后一修改时间:2024-09-23inline _DList(const _DListNodeIterator<T>& itBegin, const _DListNodeIterator<T>& itEnd) {InitData();_DListNodeIterator<T> it = itBegin;while (it != itEnd) {          Add(*it);++it;}}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 std::vector<T>& v) {InitData();for (const T& t : v){Add(t);}}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(const size_t  &nCaptionty) { _MaxBuffer = nCaptionty; }inline size_t 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,this); }inline _DListNodeReverseIterator<T> rbegin()const { return _DListNodeReverseIterator<T>(_Last,this); }/// <summary>/// /// </summary>/// <returns></returns>inline _DListNodeIterator<T> end()const{//迭代器使用的语句//for (_DListNodeIterator<int> f = dl.begin(); f != dl.end(); f++) {       }return _DListNodeIterator<T>(null,this);}/// <summary>/// /// </summary>/// <returns></returns>inline _DListNodeReverseIterator<T> rend()const{//迭代器使用的语句//for (_DListNodeIterator<int> f = dl.begin(); f != dl.end(); f++) {       }return _DListNodeReverseIterator<T>(null, this);}//-----------------------------------------------------------运算符重载/// <summary>/// 重载的下标操作符 []/// </summary>T& operator[](const size_t& 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>/// 创建时间: ???-??-??      最后一次修改时间:2024-09-20 (改用_Math::swap)    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;*/_Math::swap(pNode1->Data, pNode2->Data);return true;}/// <summary>/// 选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是:第一次从待排序的数据元素中选出最小/// 或最大)的一个元素,存放在序列的起始位置,然后再从剩余的未排序元素中寻找到最小(大)元素,然后放到已排序/// 的序列的末尾。以此类推,直到全部待排序的数据元素的个数为零。选择排序是不稳定的排序方法。/// </summary>/// <typeparam name="T"></typeparam>/// <param name="sortord"></param>/// 创建时间: ???-??-??      最后一次修改时间:2024-09-20 (改用_Math::swap)   已测试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;*/_Math::swap(tmp->Data, min->Data);}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;*/_Math::swap(tmp->Data, min->Data);}tmp = tmp->Next;}min = min->Next;tmp = min->Next;}}this->_so = sortord;  //已排序}/// <summary>/// 返回索引的节点/// </summary>inline virtual _DListNode<T>* IndexOfNode(const size_t& nPos)const{if (nPos >= _Count) //错误索引:{return NULL;}size_t nindex = 0;if (nPos > _Count / 2){_DListNode<T>* pNode = _Last;while (pNode != null){if (nindex++ == _Count - nPos - 1) { return pNode; }pNode = pNode->Prev;}}else{_DListNode<T>* pNode = _First;while (pNode != null){if (nindex++ == nPos){return pNode;}pNode = pNode->Next;}}return null;}/// <summary>/// 把节点移到最后/// </summary>/// <param name="dnCurrent"></param>/// <returns></returns>/// 创建时间: 2022-02-18      最后一次修改时间:2024-09-23inline virtual _DListNode<T>* MoveLast(_DListNode<T>* pNode){if (pNode != null) {if (pNode == _Last) {//ok}else if (pNode == _First) {  //此时最少两个节点_First = _First->Next;_First->Prev = null;_Last->Next = pNode;pNode->Prev = _Last;_Last = pNode;this->_so = _SortOrder::s_null;}else {pNode->Prev->Next = pNode->Next;pNode->Next->Prev = pNode->Prev;_Last->Next = pNode;pNode->Prev = _Last;_Last = pNode;this->_so = _SortOrder::s_null;}}return pNode;        }/// <summary>/// 把索引为nIndex的节点移到最后,并返回这个节点。/// </summary>/// <typeparam name="T"></typeparam>/// <param name="iIndex"></param>/// <returns></returns>/// 创建时间: ???-??-??      最后一次修改时间:2024-09-22  inline virtual  _DListNode<T>* MoveLast(const size_t& nIndex){return MoveLast(IndexOfNode(nIndex));}/// <summary>/// 把索引为nIndex的节点移到最前/// </summary>/// <param name="iIndex"></param>inline virtual bool MoveFirst(const size_t& nIndex){_DListNode<T>* pNode = IndexOfNode(nIndex);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>/// 创建时间: ????-??-??      最后一次修改时间:2024-09-22inline virtual _DListNode<T>* Add(const T& tValue){_DListNode<T>* pResult;if (_Count == 0){//_First = new _DListNode<T>(item);pResult = _Memory::New< _DListNode<T> >(1);_First = pResult;_First->Data = tValue;_First->Next = null;_First->Prev = null;_Last = _First;}else{pResult = _Memory::New< _DListNode<T> >(1);pResult->Data = tValue;pResult->Next = null;pResult->Prev = _Last;_Last->Next = pResult;_Last = pResult;}++_Count;this->_so = _SortOrder::s_null;   //要重新排序return pResult;}/// <summary>/// 添加一个链表/// </summary>/// 创建时间: ????-??-??      最后一次修改时间:2024-09-22inline _DListNode<T>* Add(const _DList<T>& dList){_DListNode<T>* pResult = null;_DListNode<T>* pNode = dList._First;while (pNode != null){if (pResult == null) pResult = Add(pNode->Data);elseAdd(pNode->Data);pNode = pNode->Next;}return pResult;}
protected:/// <summary>/// 在结点pItemNode后面插入一个结点,成功,返回新的结点,否则返回NUll;/// 如果pItemNote == null,则默认在后面添加一个项。/// </summary>/// <typeparam name="T"></typeparam>/// <param name="pItemNode">当前结点</param>/// <param name="rValue"></param>/// <returns></returns>/// 创建时间: ????-??-??      最后一次修改时间:2024-09-22inline virtual _DListNode<T>* InserNodeBack(_DListNode<T>* pNoteItem, const T& tValue){if (pNoteItem == null || _Count == 0) return this->Add(tValue);this->SortOrder = _SortOrder::s_null;_DListNode<T>* pNode = _Memory::New<_DListNode<T>>(1);pNode->Data = tValue;//pNodepNode->Prev = pNoteItem;pNode->Next = pNoteItem->Next;//pListItem->Nextif (pNoteItem->Next != null) {pNoteItem->Next->Prev = pNode;}else{_Last = pNode;}//--pNoteItempNoteItem->Next = pNode;++_Count;return pNode;}/// <summary>/// 在结点pNoteItem前面插入一个结点,成功,返回新的结点,否则返回null/// 如果pItemNote == null,则默认在后面添加一个项。/// </summary>/// <typeparam name="T"></typeparam>/// <param name="pListItem"></param>/// <param name="rData"></param>/// <returns></returns>/// 创建时间: ????-??-??      最后一次修改时间:2024-09-22inline virtual _DListNode<T>* InserNodeFront(_DListNode<T>* pNoteItem, const T& tValue){if (pNoteItem == null || _Count == 0) return this->Add(tValue);this->SortOrder = _SortOrder::s_null;if (pNoteItem == null) return null;_DListNode<T>* pNode = _Memory::New<_DListNode<T>>(1);pNode->Data = tValue;//pNode            pNode->Next = pNoteItem;pNode->Prev = pNoteItem->Prev;//--pListItem->Previf (pNoteItem->Prev != null){pNoteItem->Prev->Next = pNode;}else{_First = pNode;}//pNoteItempNoteItem->Prev = 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 size_t& nIndex){if (nIndex >= _Count) return false;_DListNode<T>* pNode = _First;size_t  nCount = 0;while (pNode != null){if (nCount == nIndex){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;++nCount;}return false;}/// <summary>/// 在节点中查找一项数据,这项数据值与tData相同/// </summary>/// <param name="tData"></param>/// <returns></returns>/// 创建时间:????-??-?? 最后一次修改时间:2024-09-20inline _DListNode<T>* FindNodeItem(const T& tValue)const{switch (this->_so){case _SortOrder::s_Maxmin:{if (_Count == 0){return null;}if (_Count == 1){//return (_First.Data as IComparable).CompareTo(tValue) == 0 ? _First : null;return _First->Data == tValue ? _First : null;}if (_Count == 2){//if ((_First.Data as IComparable).CompareTo(tValue) == 0) return _First;//if ((_First.Next.Data as IComparable).CompareTo(tValue) == 0) return _First.Next;if (_First->Data == tValue) return _First;if (_First->Next->Data == tValue) 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 = (tValue as IComparable).CompareTo(ld.Data);if (tValue > pNode->Data){if (nRight == nLeft || nPos == nLeft){return null;}nRight = nPos - 1;}else if (tValue < 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(tValue) == 0 ? _First : null;return _First->Data == tValue ? _First : null;}if (_Count == 2){//if ((_First.Data as IComparable).CompareTo(tValue) == 0) return _First;//if ((_First.Next.Data as IComparable).CompareTo(tValue) == 0) return _First.Next;if (_First->Data == tValue) return _First;if (_First->Next->Data == tValue) 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 = (tValue as IComparable).CompareTo(ld.Data);if (tValue < pNode->Data){if (nRight == nLeft || nPos == nLeft){return null;}nRight = nPos - 1;}else if (tValue > 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 (tValue == pNode->Data){return pNode;}/*if (pNode.Data.Equals(tValue)){return pNode;}*/pNode = pNode->Next;}break;}default:{return null;}}return null;}inline _DListNode<T>* Find(const T& tValue)const { return FindNodeItem(tValue); }/// <summary>/// 在链接中查找节点,返回节点的索引/// </summary>/// <param name="pFind"></param>/// <returns></returns>/// 创建时间:2024-07-03 最后一次修改时间:2024-07-03inline int FindNodeIndex(const _DListNode<T>* pFind)const{if (pFind != null){_DListNode<T>* pNode = _First;int nIndex = 0;while (pNode != null){if (pNode == pFind)return nIndex;pNode = pNode->Next;++nIndex;  }}return -1;}/// <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 size_t  &nIndex, const T& tItem){InserNodeBack(IndexOfNode(nIndex), tItem);}/// <summary>/// 在最前面插入一项/// </summary>/// <param name="tItem"></param>/// 创建时间: 2024-04-16      最后一次修改时间:2024-09-19inline void inseart_front(const T& tItem){this->SortOrder = _SortOrder::s_null;_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;}inline _DListNode<T>* inseart_back(_DListNode<T>* pNode, const T& tData) {return this->InserNodeBack(pNode, tData);}inline _DListNode<T>* inseart_front(_DListNode<T>* pNode, const T& tData) {return this->InserNodeFront(pNode, tData);}/// <summary>/// 删除索引位置为nIndex的元素,并返回删除的元素值的拷贝,如果索引值nIndex = -1,则默认删除为最后一个元素。/// </summary>/// <param name="nIndex"></param>/// <returns></returns>/// 创建时间: 2023-04-08      最后一次修改时间:2023-04-09inline T Python_pop(const size_t nIndex = npos){if (nIndex == npos){         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& tItem) { Add(tItem); }inline void push_front(const T& tItem) { this->inseart_front(tItem);}public: //------------------------------------------------------------------重写/// <summary>/// 转换为字符串/// </summary>/// <returns></returns>/// 创建时间: 2023-05-16      最后一次修改时间:2024-07-23inline 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;if(_Count > 0){//是否继承处_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 if (typeid(T) == typeid(std::string)) {std::string* ps;if (_Count <= 0){}else if (_Count == 1){ps = (std::string*)(&_First->Data);sResult.Add(_t("\""));sResult.Add(_string(ps->c_str()));sResult.Add(_t("\""));}else{_DListNode<T>* dn = this->_First;while (dn != _Last){ps = (std::string*)(&dn->Data);sResult.Add(_t("\""));sResult.Add(_string(ps->c_str()));sResult.Add(_t("\""));sResult.Add(_t(','));dn = dn->Next;}ps = (std::string*)(&_Last->Data);sResult.Add(_t("\""));sResult.Add(_string(ps->c_str()));sResult.Add(_t("\""));}}else  //所有继承自 _Object 类的数据类型都可以{sResult.Add(_t("_LDList::ToSplitString重写,数据类型为:"));sResult.Add(_string(typeid(T).name()));            }}}sResult.Add(_t("}"));return sResult;}inline _string ToString()const{return ToSplitString(_t(""));}////std/// <summary>/// 在_Where位置前插入[itBegin,itEnd)(用法与std::list::insert要一样)/// 注意:std旧重版itBegin和itEnd不能指向与目的位置相同的容器,在新标准版可以。/// </summary>/// <typeparam name="IteratorClass"></typeparam>/// <param name="_Where"></param>/// <param name="itBegin"></param>/// <param name="itEnd"></param>/// 创建时间: 2024-09-22      最后一次修改时间:2024-09-22 (已测试)template<class IteratorClass>inline _DListNodeIterator<T> std_insert(const _DListNodeIterator<T>& _Where, const IteratorClass& itBegin,const IteratorClass& itEnd) {/*list slist;      //运行时错误:迭代器表示要拷贝的范围,不能指向与目的位置相同的容器slist.insert(slist.begin(),slist.begin(),slist.end());*/if (typeid(_DListNodeIterator<T>) == typeid(IteratorClass)) {_DListNodeIterator<T>* pbegin = (_DListNodeIterator<T>*)(&itBegin);_DListNodeIterator<T>* pend = (_DListNodeIterator<T>*)(&itEnd);//lassert(_Where._pCurrentList != p->_pCurrentList,"不能插入指向相同容器的元素");if (_Where._pCurrentList == pbegin->_pCurrentList) {//创建一个临时链表,会影响性能_DList<T> tmp(*pbegin,*pend);return std_insert(_Where, tmp.begin(), tmp.end());}            }     IteratorClass tmp = itBegin;_DListNode<T>* pReulst = null;if (_Where._Ptr == null) {while (tmp != itEnd) {if (pReulst == null) {//保存第一次插入的结点,以便返回pReulst = this->inseart_back(_Last, *tmp);}elsethis->inseart_back(_Last, *tmp);++tmp;}}else {auto ptr = _Where._Ptr;while (tmp != itEnd) {if (pReulst == null) //第一次,在前面插入第一项{ptr = this->inseart_front(ptr, *tmp);//保存第一次插入的结点,以便返回pReulst = ptr;}else { //第二次开始,在插入的第一项后面依次插入ptr = this->inseart_back(ptr, *tmp);}++tmp;}}return _DListNodeIterator<T>(pReulst, this);}/// <summary>/// std::insert/// </summary>/// <param name="_Where"></param>/// <param name="_Ilist"></param>/// <returns></returns>/// 创建时间: 2024-09-22      最后一次修改时间:2024-09-22 (已测试)inline _DListNodeIterator<T> std_insert(const _DListNodeIterator<T>& _Where,std::initializer_list<T> _Ilist) {return std_insert(_Where, _Ilist.begin(), _Ilist.end());}/// <summary>/// std::insert/// </summary>/// <param name="_Where"></param>/// <param name="tValue"></param>/// <returns></returns>/// 创建时间: 2024-09-22      最后一次修改时间:2024-09-22  (已测试)inline _DListNodeIterator<T> std_insert(const _DListNodeIterator<T>& _Where, const T& tValue) {if (_Where._Ptr == null)return _DListNodeIterator<T>(inseart_back(_Last, tValue), this);elsereturn _DListNodeIterator<T>(inseart_front(_Where._Ptr, tValue), this);}}; //--------------------------------------------------------------------------DList////SortedDList///// <summary>
///  C#语句:public class SortList<T> : _DList<T>
/// </summary>
/// <typeparam name="T"></typeparam>
template<class T>
class SortedDList : public _DList<T>
{};////_StrList// 
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 _DListNode<T>* 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;}}/// <summary>/// 添加拷贝nStartPos和nEndPos之间的字符,包括nStartPos和nEndPos。/// </summary>/// <param name="str"></param>/// <param name="nStartPos"></param>/// <param name="nEndPos"></param>/// <returns></returns>/// 创建时间:  ????-??-??   最后一次修改时间:????-??-??   已测试(2024-08-16 )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);}
};////_UStrList// 
/// <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>/// 创建时间: ????-??-??      最后一次修改时间:2024-09-23 (已测试)_DListNode<T>* Add(const T& item)override{  bool bFind = false;_DListNode<T>* dnTemp = this->_First;while (dnTemp != null){if (dnTemp->Data == item){return this->MoveLast(dnTemp);             }dnTemp = dnTemp->Next;}return _StrList<T>::Add(item);       }};////_UStrListCI// 
/// <summary>
/// 值都是唯一的字符串列表,  Case Insensitive(不区分大小写)
/// </summary>
template<class T>
class _UStrListCI : public _StrList<T>
{public:/// <summary>/// 加入一个串,如果这个串存在,则把这项移到最后。/// </summary>/// <param name="item"></param>/// 创建时间: ????-??-??      最后一次修改时间:2024-09-23_DListNode<T>* Add(const T& item)override{bool bFind = false;_DListNode<T>* dnTemp = this->_First;while (dnTemp != null){if (dnTemp->Data.csharp_ToLower() == item.csharp_ToLower()){return this->MoveLast(dnTemp);}dnTemp = dnTemp->Next;}return _StrList<T>::Add(item);    }/*/// <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;}*/
};////_SStrList// 
/// <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;}};////_SUStrList// 
/// <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){}};////_SUStrListUI// 
/// <summary>
/// _SUStrListUI 值都是唯一,且已排序的字符串列表,不区分大小写
/// </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;}};// _SUStrListUI_LF_END_
#endif


http://www.ppmy.cn/embedded/118451.html

相关文章

信号分解降噪 | Matlab实现基于TVFEMD-IMF能量熵增量的数据降噪方法

信号分解降噪 | Matlab实现基于TVFEMD-IMF能量熵增量的数据降噪方法 目录 信号分解降噪 | Matlab实现基于TVFEMD-IMF能量熵增量的数据降噪方法效果一览基本介绍程序设计参考资料 效果一览 基本介绍 信号分解降噪 | Matlab实现基于TVFEMD-IMF能量熵增量的数据降噪方法。该方法引…

如何将MySQL卸载干净(win11)

相信点进来的你肯定是遇到了这个问题&#xff0c;那就是在安装MySQL的时候操作错误&#xff0c;最后结果不是自己想要的。卸载重新安装又发现安装不了。其实最主要的原因就是没有将MySQL卸载干净&#xff0c;那么如何把MySQL卸载干净&#xff1f;下面本篇文章就来给大家一步步介…

【MySQL】字符集与Collation

今天做项目&#xff0c;突然发现&#xff0c;项目中使用的MySQL的库排序规则是 utf8mb4_general_ci&#xff0c;而我自己用的MySQL8默认库规则是utf8mb4_0900_ai_ci&#xff0c;于是想要弄清楚 出处&#xff08;写的非常详细&#xff09;&#xff1a;mysql设置了utf8mb4&#x…

828华为云征文|使用Flexus X实例安装宝塔面板教学

目录 一、Flexus X实例简介 1.1 概述 1.2 产品规格 二、切换操作系统 2.1 Huawei Cloud EulerOS 2.0 标准版 2.2 切换镜像 三、部署宝塔面板 3.1 安装宝塔面板 3.2 放通安全组规则 3.3 登录宝塔面板 四、使用感受 4.1 柔性算力随心配 4.2 一直加速一直快 4.3 越用…

【QT】QWidget 重要属性

文章目录 enabledgeometrywindowTitlewindowIconqrc 机制windowOpacitycursorfontQFont toolTip 和 toolTipDurationfocusPolicyQt::FocusPolicy styleSheet enabled 作用&#xff1a;设置控件是否可使用. true 表⽰可用, false 表⽰禁用. 对应的API bool isEnabled(); // 获…

Redis常用命令笔记

1、启动Redis服务端 $ redis-server 2、启动Redis客户端&#xff0c;--raw防止中文乱码 $ redis-cli --raw 3、读写数据 > set key1 value1 > get key1 > exists key1 > type key1 > del key1 nx&#xff1a;没有key1的情况下成功 xx&#xff1a;有key1的…

Linux云计算 |【第四阶段】NOSQL-DAY1

主要内容&#xff1a; NoSQL概述&#xff08;RDBMS、NoSQL&#xff09;、部署Redis服务、Redis数据类型&#xff08;字符串、散列类型、列表类型、集合类型、有序集合类型&#xff09;、Redis其它操作命令、修改Redis服务运行参数、部署支持PHP和Redis的Nginx服务器 一、NoSQL…

Vue引入js脚本问题记录(附解决办法)

目录 一、需求 二、import引入问题记录 三、解决方式 一、需求 我想在我的Vue项目中引入jquery.js和bootstrap.js这种脚本文件&#xff0c;但发现不能单纯的import引入&#xff0c;问题如下。 二、import引入问题记录 我直接这么引入&#xff0c;发现控制台报错TypeError: …