C++实现list类

本文详细探讨了C++中list类的实现原理,包括双向链表的结构设计、迭代器的工作方式以及常见操作如插入、删除、遍历等的内部逻辑。通过对源码的分析,读者将深入理解C++标准库中的list容器如何高效地支持各种复杂数据结构操作。
#pragma once
#ifndef DSA_LIST_H
#define DSA_LIST_H
#define Posi(T) ListNode<T>*                         //列表位置节点

template<typename T>struct ListNode//列表节点模板类实现
{
    T data;//数值
    Posi(T)pred;//前驱
    Posi(T)succ;//后继
    ListNode() {}//针对header和railer的构造
    ListNode(T e, Posi(T)p = nullptr, Posi(T)s = nullptr) :data(e), pred(p), succ(s) {}//构造
    Posi(T)inserAsPred(T const&e);//前插入
    Posi(T)inserAsSucc(T const&e);//后插入

};

template<typename T>Posi(T) ListNode<T>::inserAsPred(T const& e)
{
    Posi(T)x = new ListNode(e,pred,this);//创建node
    pred->succ = x; pred = x;
    return x;

}
template<typename T>Posi(T) ListNode<T>::inserAsSucc(T const& e)
{
    Posi(T)x = new ListNode(e, this, succ);
    succ->pred = x; succ = x;
    return x;
}

 template<typename T>class List
 {
 private:int _size; T* _elem;//规模,数据
         Posi(T)header;Posi(T) trailer;//头尾哨兵
 public:int size() { return _size; }//返回规模
        void init();//链表初始化
        List() { init(); }
        Posi(T)first() { return header->succ; }//返回首节点
        Posi(T)last() { return trailer->pred; }//返回末节点
        Posi(T) insertAsFirst(T const& e);//作为首节点插入
        Posi(T) insertAslast(T const& e);//作为尾节点插入
        Posi(T) insertA(Posi(T)p,T e);//插入在P之后
        Posi(T)insertB(Posi(T)p,T e);//插入在P之前
        T  remove(Posi(T)p);//移除并返回其数值
        void sort(Posi(T)p,int n);//排序
        Posi(T) find(T const&e, int n , Posi(T)p );//查找e并返回秩
        Posi(T) find(T const&e) { return find(e, _size, trailer); }
        Posi(T) search(T e,int n,Posi(T)p);//有序链表的查找p的n个真前驱中不大于P的最后者
        int List<T>::uniquify();//有序链表的去重
        void deduplicate();//无序链表的去重
        void traverse();//链表的遍历
        void selectionSort(Posi(T)p, int n);//从P开始之后的n个节点排序
        void insertSort(Posi(T)p, int n);//插入排序
        void mergeSort(Posi(T)&p, int n);//归并排序
        void merge(Posi(T)&p, int n, List<T>&L, Posi(T)q, int m);//合并
        T& operator[](int rank);//重载[]操作符
        void copyNodes(Posi(T)p, int n);//复制
        Posi(T) selectMax(Posi(T)p, int n);//选位置p之后n个节点中最大的(包括p)
        ~List() { clear(); delete  header; delete trailer; };//析构函数
        int  clear();//清空列表
 };

 template<typename T>void List<T>::init()
 {
     header = new ListNode<T>;//创建头指针
     trailer = new ListNode<T>;//创建尾指针
     header->succ = trailer; header->pred = nullptr;//互联
     trailer->pred = header; trailer->succ = nullptr;//互联
     _size = 0;//记录规模
 }

 template<typename T>void List<T>::sort(Posi(T)p, int n)
 {
     switch (rand() % 3)
     {
     case 1:insertSort(p, n); break;
     case 2:selectionSort(p, n); break;
     case 3:mergeSort(p, n); break;
     }
 }

 template<typename T>Posi(T) List<T>::insertB(Posi(T)p, T e)
 {
     _size++;
     return p->inserAsPred(e);
 }

 template<typename T>Posi(T) List<T>::insertA(Posi(T)p, T e)
 {
     _size++;
     return p->inserAsSucc(e);
 }

 template<typename T>int List<T>::clear()
 {
     while (0 < _size)
     {
         remove(header->succ);          //反复删除header的后继
     }
     return 0;
 }

 template<typename T>void List<T>::copyNodes(Posi(T)p, int n)
 {
     init();
     while(n--)
     {
         insertAslast(p->data);
         p = p->succ;
     }
 }

 template<typename T>Posi(T) List<T>::insertAsFirst(T const& e)//作为首元素插入
 {
    return insertA(header,e);
 }

 template<typename T>Posi(T) List<T>::insertAslast(T const& e)//作为尾元素插入
 {
     return insertB(trailer,e);
 }

 template<typename T>T& List<T>::operator[] (int rank)
 {
     Posi(T)p =first();//从首节点出发
     while (rank--)
         p = p->succ;           //依次后移
     return p->data;            //返回数据
 }

 template<typename T>Posi(T) List<T>::find(T const&e,int n,Posi(T)p)//节点p的n个真前驱中找到秩最大的那个
 {
     while (0 < n--)
         if (e == (p = p->pred)->data)return p;
     cout << "查找失败" << endl;
     return nullptr;
 }

 template<typename T>T List<T>::remove(Posi(T)p)
 {
     T temp = p->data;
     p->pred->succ = p->succ;
     p->succ->pred = p->pred;
     delete p;
     _size--;
     return temp;
 }

 template<typename T>void List<T>::deduplicate()
 {
     if (_size < 2)return;
     Posi(T)p = first();
     int rank = 1;
     while (trailer != (p = p->succ))
     {
         Posi(T)q = find(p->data, rank, p);//在p的r个前驱中找雷同者
         q ? remove(q) : rank++;
     }
 }

 template<typename T>void List<T>::traverse()//
 {
     Posi(T)p = first();
     while (p != trailer)
     {
         cout << p->data << "";
         p = p->succ;
     }
 }

 template<typename T>void List<T>::selectionSort(Posi(T)p,int n)//选择排序
 {
     Posi(T)head = p->pred; Posi(T)tail = p;
     for(int i=0;i<n;i++)tail = tail->succ;
     while (1 < n)                                      //反复从待排序区选出最大者,并移至有序区间前端
     {
         insertB(tail, remove(selectMax(head->succ, n)));
         tail = tail->pred; n--;
     }
 }

 template<typename T>Posi(T) List<T>::selectMax(Posi(T)p, int n)
 {
     Posi(T)Max = p;
     while (1 < n--)
     {
         if (Max->data < (p = p->succ)->data)Max = p;
     }
     return Max;
 }

 template<typename T>int List<T>::uniquify()
 {
     int old_size = _size;
     if (_size < 2)return 0;//平凡链表无需去重
     Posi(T)temp = first();
     while (temp!=trailer)
     {
         if (temp->data == (temp->succ)->data)
             remove(temp->succ);
         temp = temp->succ;
     }
     return old_size-_size;
 }

 template<typename T>Posi(T) List<T>::search(T e, int n, Posi(T)p)
 {
     while (0<=n--)                 //--优先级大于<
     {
         if((p=p->pred)->data<=e)
             break;
     }
     return p;
 }
 template<typename T>void List<T>::insertSort(Posi(T)p, int n)
 {
     for (int r = 0; r < n; r++)
     {
         insertA(search(p->data, r, p), p->data);//查找合适的位置插入
         p = p->succ; remove(p->pred);//转向下一节点
    }
 }
 template<typename T>void List<T>::merge(Posi(T)&p, int n, List<T>&L, Posi(T)q, int m)
 {
     Posi(T)pp = p->pred;
     while (0 < m)
     {
         if (0 < n&&p->data <=q->data)
         {
             if((p=p->succ)==q)
                 break;
             n--;
         }
         else
         {
             insertB(p, L.remove((q = q->succ)->pred));
             m--;
         }
     }
     p = pp->succ;//确定归并后的新起点
 }
 template<typename T>void List<T>::mergeSort(Posi(T)&p, int n)//一定是传引用!!!
 {
     if (n < 2)return;
     int m = n >> 1;//以中点为界
     Posi(T)q = p;
     for (int i = 0; i < m; i++)q = q->succ;
     mergeSort(p, m);
     mergeSort(q, n - m);
     merge(p, m, *this, q, n - m);//归并
 }
#endif//DSA_LIST_H
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值