空间配置器测试报告

一. 空间配置器基本原理

空间配置器原理和实现见空间配置器的实现

二. 利用trace跟踪调试

对于内存池的内部实现过程还是比较复杂的,虽然代码量,函数比较简单。但是调用过程可能比较复杂。这时,如果我们选择debug调试,过程会相当的繁琐,需要仔细记录调用堆栈过程以及数据流向,逻辑变更等。
所以,就使用Trace进行跟踪,打印数据流向,逻辑走向,文件,函数,方法,行位置。那么我们就能根据这个记录进行程序的排错以及调优了。
利用宏打印文件,行,函数位置,然后利用可变参数列表方式接收代码中具体位置的记录跟踪。

#include <stdarg.h>
#define _DEBUG_
static string GetFileName(const string& path) 
{        
    char ch = '/' ; 
   #ifdef _WIN32       
    ch = '\\';
   #endif
   size_t pos = path.rfind(ch);        
   if (pos == string::npos)                
   return path;        
   else
   return path.substr(pos + 1);
}

inline static void _trace_debug(const char * funcName, const char * fileName, int line, char* format, ...) 
{
    #ifdef _DEBUG_
    fprintf(stdout, "[%s:%d]%s", GetFileName(fileName).c_str(), line, funcName);
    // 输出用户信息        
    va_list args;        
    va_start(args, format);        
    vfprintf(stdout, format, args);       
    va_end(args); 
   #endif
}
#define __TRACE_DEBUG(...) _trace_debug(__FUNCDNAME__, __FILE__, __LINE__, __VA_ARGS__);

测试结果如下:
这里写图片描述
通过对测试结果的计算和代码相比对,程序无bug,并能正确申请和分配空间。

三. 给容器vector和list分配空间

vector和list是标准序列式容器,也是最简单的容器,选择vector和list作为测试容器,一方面是比较简单容易,另一方面是vector需要连续空间,可以测试一级空间配置器,list是链表,是小结点,可以测试二级空间配置器。
测试结果:
在利用空间配置器为vector和list分配空间后,vector和list可以正确运行和使用。
vector和list代码见后面。

四. 空间配置器的问题
  1. 内存池的空间何时释放 ?
    答:在二级空间配置器中,空间没有释放的记录,没有归还给系统。一般情况下,内存池的空间会挂到自由链表中。在程序结束时,空间释放。
  2. 内碎片的问题,自由链表所挂区块都是8的整数倍,因此当我们需要非8倍数的区块,往往会导致浪费,比如我只要1字节的大小,但是自由链表最低分配8块,也就是浪费了7字节,我以为这也就是通常的以空间换时间的做法,这一点在计算机科学中很常见。
  3. 假如我不断的开辟小块内存,最后将整个heap上的内存都挂在了自由链表上,但是都没有用这些空间,再想要开辟一个大块内存的话会开辟失败。
  4. 但是总体来看,空间配置器的效率还是很高的。

vector和list代码:

#pragma once
#include "Allocate.h"
#include "Iterator.h"
#include "Uninitialized.h"
#include "Construct.h"

template<class T, class alloc = Alloc>
class Vector
{
public:
    // * 值类型
    typedef T ValueType;

    // * 指针类型
    typedef ValueType* Pointer;
    typedef const ValueType* ConstPointer;

    // * 引用类型
    typedef ValueType& Reference;
    typedef const ValueType& ConstReference;

    // * 迭代器类型
    typedef ValueType* Iterator;
    typedef const ValueType* ConstIterator;

    // * 反向迭代器类型
    typedef ReverseIterator<ConstIterator> ConstReverseIterator;
    typedef ReverseIterator<Iterator> ReverseIterator;

    typedef size_t SizeType;
    typedef ptrdiff_t DifferenceType;  //ptrdiff_t用来保存两个指针减法操作的结果

    // * 向量的专属迭代器,每次分配或者释放一个ValueType类型的空间,使用alloc分配
    typedef SimpleAlloc<ValueType, alloc> DataAllocator;
protected:
    /* 向量的管理
    start指向开始,
    finish指向最后一个数据的下一个位置
    endOfStorage指向最后一个空间的下一个位置
    */
    Iterator start;
    Iterator finish;
    Iterator endOfStorage;
public:
    // * 几个基本函数(构造,析构,拷贝构造,赋值运算符)
    // * 构造函数
    Vector()
        : start(0), finish(0), endOfStorage(0) 
    {}

    // * 构造一个向量,有n个值为value的元素
    Vector(SizeType n, const ValueType& value) 
    { 
        Fill_Initialize(n, value); 
    }
    // 对只有一个数据成员的类,单参数的构造函数容易发生隐式转换,前面的explicit可以防止这个发生,
    //但是对于Vecotr有三个数据成员的类,前面的explicit可加可不加
    explicit Vector(SizeType n) 
    { 
        Fill_Initialize(n, T()); 
    }
    // * 由一段区间构造一个向量
    Vector(ConstIterator first, ConstIterator last)
    {
        SizeType n = 0;
        Distance(first, last, n);
        start = AllocateAndCopy(n, first, last);
        finish = start + n;
        endOfStorage = finish;
    }
    // * 拷贝构造
    Vector(const Vector<T, alloc>& x)
    {
        start = AllocateAndCopy(x.Size(), x.Begin(), x.End());
        finish = start + x.Size();
        endOfStorage = finish;
    }
    // * 析构函数
    ~Vector()
    {
        // * 析构所有元素
        Destroy(start, finish);
        // * 释放所有空间
        Deallocate();
    }
    /*  赋值运算符的传统写法 */
    //Vector<T, alloc> & operator=(const Vector<T, alloc>& x)
    //{
    //  if (&x != this)
    //  {
    //      SizeType sizeOfX = x.Size();
    //      if (sizeOfX > Capacity())    // * x的size比我当前的容量还大,需要申请空间
    //      {
    //          Iterator tmp = AllocateAndCopy(x.End() - x.Begin(), x.Begin(), x.End());
    //          
    //          // * 释放原有空间
    //          Destroy(start, finish);
    //          Deallocate();
    //          // * 修改范围
    //          start = tmp;
    //          endOfStorage = start + sizeOfX;
    //      }
    //      else if (Size() > x.Size())    // * x的size比较小,只拷x.Size()个元素,当前向量中之后的元素析构掉
    //      {
    //          Iterator end = copy(x.Begin(), x.End(), start);
    //          Destroy(end, finish);
    //      }
    //      else                           // * x的size比较大,前半段拷贝,后半段先初始化在拷贝(如果是POD类型,该函数还是调用的copy)
    //      {
    //          copy(x.Begin(), x.End(), start);
    //          UninitializedCopy(x.Begin() + Size(), x.End(), finish);
    //      }
    //      finish = start + sizeOfX;
    //  }
    //  return *this;
    //}

    /*  赋值运算符的简洁写法 */
    Vector<T, alloc> & operator=(Vector<T, alloc> x)
    {
        Swap(x);
        return *this;
    }

public:
    // * 向量的对外接口
    Iterator Begin() 
    { 
        return start; 
    };
    ConstIterator Begin()const 
    { 
        return start; 
    };
    Iterator End() 
    { 
        return finish; 
    };
    ConstIterator End()const 
    { 
        return finish; 
    };
    /*
    RBegin()
    RBegin()
    REnd()
    REnd()
    */
    /* * func: 返回的是现有元素个数 */
    SizeType Size()const 
    { 
        return End() - Begin(); 
    }

    SizeType MaxSize() 
    { 
        return SizeType(SizeType(-1) / sizeof(T));
    }

    /* * func: 修改向量的现有元素个数至newSize,如果现有元素个数newSize,则删除后面一部分; 
    反之在尾端插入一部分 x */

    void Resize(SizeType newSize, ValueType& x)
    {
        if (newSize < Size())
            Erase(Begin() + newSize, finish);
        else
            Insert(End(), newSize - Size(), x);
    }
    /* * func: 返回的是容量,即向量所有申请的空间大小 */
    SizeType Capacity()const 
    { 
        return endOfStorage - start; 
    };
    bool Empty()const 
    { 
        return End() == Begin(); 
    };

    Reference operator[](SizeType n) 
    {
        return *(Begin() + n); 
    };

    ConstReference operator[](SizeType n)const
    { 
        return *(Begin() + n); 
    }
    Reference Front() 
    { 
        return *Begin(); 
    }

    ConstReference Front() const 
    { 
        return *Begin(); 
    }

    Reference Back() 
    {
        return *(End() - 1); 
    }

    ConstReference Back() const 
    { 
        return *(End() - 1); 
    }

    /* * func: 保留,把向量的 容量 扩充 至n,只有当向量的当前容量小于n时,该函数才会做事情 */
    void Reserve(SizeType n)
    {
        if (Capacity() < n)
        {
            // * 拷贝数据到一个新的地址,该空间长度为 n
            SizeType oldSize = Size();
            Iterator tmp = AllocateAndCopy(n, start, finish);

            // * 销毁原有空间
            Destroy(start, finish);
            Deallocate();
            // * 重新修改范围
            start = tmp;
            finish = start + oldSize;
            endOfStorage = start + n;
        }
    }
    /* * func: 在向量尾部插入数据 x */
    void PushBack(const T& x)
    {
        if (finish != endOfStorage)
            Construct(finish++, x);
        else
            Insert_Aux(End(), x);
    }
    /* * func: 尾部删除一个元素 */
    void PopBack()
    {
        --finish;
        Destroy(finish);
    }
    /* * func: 删除向量中的所有元素,但是不销毁向量 */
    void Clear() 
    { 
        Erase(Begin(), End()); 
    }
    /* * func: 交换两个向量 */
    void Swap(Vector<T, Alloc> &x)
    {
        std::swap(start, x.start);
        std::swap(finish, x.finish);
        std::swap(endOfStorage, x.endOfStorage);
    }

    /* * func: 在position处插入元素 x */
    Iterator Insert(Iterator position, const ValueType& x)
    {
        // * 有空闲空间,并且插入点是在最后面,直接构造一个对象
        if (finish != endOfStorage && position == End())
        {
            Construct(position, x);
            ++finish;
        }
        // * 如果没有空闲空间 | position是向量中间某一个位置,需要申请空间 | 往后移动元素
        else
            Insert_Aux(position, x);

        return position;
    }

    /* * func: 在position处插入默认元素 */
    Iterator Insert(Iterator position) 
    { 
        return Insert(position, T()); 
    }
    /* * func: 在position位置插入一段区间 [first, last) */
    void Insert(Iterator position, ConstIterator first, ConstIterator last)
    {
        // * 只有当[first, last)不空时才去做一些事
        if (first != last)
        {
            SizeType n = 0;
            Distance(first, last, n);

            if (endOfStorage - finish > n)  // 剩余空间够用
            {
                SizeType elemsAfter = finish - position;
                Iterator oldFinish = finish;
                if (elemsAfter > n)
                {
                    // * 拷贝finish之前的n个数据到finish
                    UninitializedCopy(finish - n, finish, finish);
                    finish += n;
                    // * 剩余的elemsAfter-n个元素往后拷贝
                    copy_backward(position, oldFinish - n, oldFinish);
                    // * 填充新数据到指定位置
                    copy(first, last, position);
                }
                else    // elemsAfter <= n
                {
                    // * 先把[first, last)区间的后面几个元素拷贝到原区间尾部
                    UninitializedCopy(first + elemsAfter, last, finish);
                    finish += n - elemsAfter;

                    // * 把elemsAfter个剩余元素拷贝到尾部
                    UninitializedCopy(position, oldFinish, finish);
                    finish += elemsAfter;

                    // * 把elemsAfter个新元素拷贝到position
                    copy(first, first + elemsAfter, position);
                }
            }  /* if endOfStorage - finish > n */

            else  // * endOfStorage - finish <= n 说明空间不够用
            {
                // * 申请空间
                SizeType oldSize = Size();
                SizeType len = oldSize + max(oldSize, n);
                Iterator newStart = DataAllocator::Allocate(len);
                Iterator newFinish = newStart;

                // * 拷贝position之前的元素到新空间, 拷贝[start, position)到newStart
                newFinish = UninitializedCopy(start, position, newStart);
                // * 追加新数据到新空间的尾部,拷贝[first, last)到newFinish
                newFinish = UninitializedCopy(first, last, newFinish);
                // * 追加position之后的元素到新空间的尾部,拷贝[position, finish)到newFinish
                newFinish = UninitializedCopy(position, finish, newFinish);
                // * 释放原空间
                Destroy(start, finish);
                Deallocate();
                // * 更改范围
                start = newStart;
                finish = newFinish;
                endOfStorage = start + len;
            }  /* else */
        }  /* if first != last */
    }
    /* * func: 在position位置插入n个值为x的元素 */
    void Insert(Iterator position, SizeType n, ValueType& x)
    {
        if (n != 0)
        {
            if (endOfStorage - finish >= n)  // 剩余空间够用
            {
                ValueType xCopy = x;
                SizeType elemsAfter = finish - position;
                Iterator oldFinish = finish;
                if (elemsAfter > n)
                {
                    // * 拷贝finish之前的n个数据到finish
                    UninitializedCopy(finish - n, finish, finish);
                    finish += n;
                    // * 剩余的elemsAfter-n个元素往后拷贝
                    copy_backward(position, oldFinish - n, oldFinish);
                    // * 填充新数据到指定位置
                    fill(position, position + n, xCopy);
                }
                else    // elemsAfter <= n
                {
                    // * 先把[first, last)区间的后面几个元素拷贝到原区间尾部
                    UninitializedFill_n(finish, n - elemsAfter, xCopy);
                    finish += n - elemsAfter;
                    // * 把elemsAfter个剩余元素拷贝到尾部
                    UninitializedCopy(position, oldFinish, finish);
                    finish += elemsAfter;
                    // * 把elemsAfter个新元素拷贝到position
                    fill(position, oldFinish, xCopy);
                }
            }  /* if endOfStorage - finish > n */
            else  // * endOfStorage - finish <= n 说明空间不够用
            {
                // * 申请空间
                SizeType oldSize = Size();
                SizeType len = oldSize + max(oldSize, n);
                Iterator newStart = DataAllocator::Allocate(len);
                Iterator newFinish = newStart;

                // * 拷贝position之前的元素到新空间, 拷贝[start, position)到newStart
                newFinish = UninitializedCopy(start, position, newStart);
                // * 追加新数据到新空间的尾部,拷贝[first, last)到newFinish
                newFinish = UninitializedFill_n(newFinish, n, x);
                // * 追加position之后的元素到新空间的尾部,拷贝[position, finish)到newFinish
                newFinish = UninitializedCopy(position, finish, newFinish);

                // * 释放原空间
                Destroy(start, finish);
                Deallocate();
                // * 更改范围
                start = newStart;
                finish = newFinish;
                endOfStorage = start + len;
            }  /* else */
        }  /* if n != 0 */
    }
    /* * func: 删除position位置的元素,返回position位置,现在该位置的值编程删除前position的下一个元素 */
    Iterator Erase(Iterator position)
    {
        if (position + 1 != finish)
            copy(position + 1, finish, position);
        --finish;
        Destroy(finish);
        return position;
    }

    /* * func: 删除向量中的[first, last)区间的元素,返回原来的first位置 */
    Iterator Erase(Iterator first, Iterator last)
    {
        // * 覆盖用[last, finish)区间的元素覆盖[first, last), newFinish返回last的下一个位置
        Iterator newFinish = copy(last, finish, first);
        // * 删除后面的重复元素
        Destroy(newFinish, finish);
        // * 修改新区间
        finish = newFinish;
        return first;
    }

    /* * func: 把[first, last)区间的元素赋值给向量,
    如果[first, last)区间的元素还没有当前的Size()大,就删除向量后面的所有元素 */
    void Assign(ConstIterator first, ConstIterator last)
    {
        Iterator it = Begin();
        // * 为了复用节点,首先把一些值赋给向量开始的一段元素
        for (; it != End() && first != last; ++it, ++first)
            *it = *first;
        Erase(it, End());
        for (; first != last; ++first)
            Insert(End(), *first);
    }
protected:
    // 一些内部接口

    /* * func: 在position处插入元素 x */

    template<class T>
    void Insert_Aux(Iterator position, const T& x)
    {
        if (finish != endOfStorage)
        {
            Construct(finish, *(finish - 1));
            ++finish;
            T x_copy = x;
            // * 把[position, finish-2)的元素拷贝到以 finish-1) 为末地址的空间【从后往前拷贝】
            copy_backward(position, finish - 2, finish - 1);
            //大致定义: 
            //copy_backward(first, last, result)  {hile (first != last) *--result = *--last;}
            *position = x_copy;
        }
        else    // * finish == endOfStorage,已有空间不够
        {
            const SizeType old_size = Size();
            const SizeType len = old_size != 0 ? 2 * old_size : 1;
            Iterator new_start = DataAllocator::Allocate(len);
            Iterator new_finish = new_start;
            // * 先拷贝插入点的前一部分
            //new_finish = UninitializedCopy(start, position, new_start);
            new_finish = uninitialized_copy(start, position, new_start);
            // * 在position插入当前新值
            Construct(new_finish, x);
            ++new_finish;
            // * 拷贝插入点的后一部分
            //new_finish = UninitializedCopy(position, finish, new_finish);
            new_finish = uninitialized_copy(position, finish, new_finish);
            // * 销毁之前的空间
            Destroy(Begin(), End());
            //DataAllocator::Deallocate();
            Deallocate();
            // * 修正当前的范围
            start = new_start;
            finish = new_finish;
            endOfStorage = new_start + len;
        }  /* else */

    }  /* Insert_Aux */

    /* * func: 向量初始化用,开辟n个空间,并初始化成value */
    void Fill_Initialize(SizeType n, const ValueType& value)
    {
        start = AllocateAndFill(n, value);
        finish = start + n;
        endOfStorage = finish;
    }
    /* * func: 分配n个空间,并在刚分配的空间内填充n个值为value的元素 */
    Iterator AllocateAndFill(SizeType n, const ValueType& value)
    {
        Iterator result = DataAllocator::Allocate(n);
        UninitializedFill_n(result, n, value);
        return result;
    }
    /* * func: 分配n个空间,并把[first, last)区间的元素拷贝到刚分配的空间内 */
    template<class ForwardIterator>
    Iterator AllocateAndCopy(SizeType n, ForwardIterator first, ForwardIterator last)
    {
        Iterator result = DataAllocator::Allocate(n);
        // [first, last) 拷贝到以result开始的地方
        UninitializedCopy(first, last, result);
        return result;
    }

    /* * func: 如果向量有容量,就释放所有空间 */
    void Deallocate()
    {
        if (start)
            DataAllocator::Deallocate(start, endOfStorage - start);
    }
};  /* Vector */
#pragma once
#include <stddef.h>    // * ptrdiff_t
#include "Allocate.h"
#include "Construct.h"
#include "Iterator.h"



// * 链表节点

template<class T>
struct __ListNode

{

                  T       _data;     // * 值类型
    struct __ListNode<T>* _next;     // * 指向下一个节点
    struct __ListNode<T>* _prev;     // * 指向前一个节点
    __ListNode(const T& data, struct __ListNode<T>* next = NULL, struct __ListNode<T> *prev = NULL)
        :_data(data)
        , _next(next)
        , _prev(prev)
    {}
};

// * 链表的迭代器
template<class T, class Ref, class Ptr>
struct __ListIterator
{
    typedef __ListIterator<T, T&, T*> Iterator;
    typedef __ListIterator<T, const T&, const T*> ConstIterator;
    typedef __ListIterator<T, Ref, Ptr> Self;
    // * 迭代器的五种型别
    typedef BidirectionalIteratorTag IteratorCategory;
    typedef T ValueType;
    typedef Ptr Pointer;
    typedef Ref Reference;
    typedef ptrdiff_t DifferenceType;
    // * 重定义指针类型
    typedef __ListNode<T>* LinkType;
    typedef size_t SizeType;
    typedef ptrdiff_t Difference;
    // * 几个构造函数
    __ListIterator() :_node(NULL) {}

    // * 用一个节点的指针构造

    __ListIterator(LinkType x) :_node(x) {}

    // * 拷贝构造

    __ListIterator(const Iterator &x) :_node(x._node) {}
    // * 迭代器的几个操作
    bool operator==(const Self &x) { return _node == x._node; }
    bool operator!=(const Self &x) { return !operator==(x); }
    Reference operator*() { return (*_node)._data; }
    Pointer operator->() { return &(operator*()); }
    Self& operator++()    // * 前置++
    {
        _node = (*_node)._next;
        return *this;
    }
    Self operator++(int)
    {
        Self tmp = *this;
        ++(*this);
        return tmp;
    }
    Self& operator--()    // * 前置--
    {
        _node = (*_node)._prev;
        return *this;
    }
    Self operator--(int)
    {
        Self tmp = *this;
        (*this)--;
        return *this;
    }
// * 迭代器的数据成员(一个指向链表节点的指针)
LinkType _node;
};
template <class T, class Ref, class Ptr>
inline BidirectionalIteratorTag
IteratorCategory(const __ListIterator<T, Ref, Ptr>&)      // ****** only for List
{
   return BidirectionalIteratorTag();
}
template <class T, class alloc = Alloc>
class List
{
    typedef __ListNode<T> ListNode;
  public:
    typedef T ValueType;
    typedef ValueType Pointer;
    typedef const ValueType ConstPointer;
    typedef ValueType&  Reference;
    typedef const ValueType& ConstReference;
    typedef __ListNode<T> ListNode;
    typedef ListNode* LinkType;
    typedef SimpleAlloc<ListNode, alloc> ListNodeAllocator;    // * list的专属空间配置器,构造节点用
    typedef size_t SizeType;
    typedef ptrdiff_t DifferenceType;
    // * 迭代器
    typedef typename __ListIterator<T, T&, T*>::Iterator Iterator;
    typedef typename __ListIterator<T, const T&, const T*>::ConstIterator ConstIterator;
// * 反向迭代器
    typedef ReverseIterator<ConstIterator> ConstReverseIterator;
    typedef ReverseIterator<Iterator> ReverseIterator;
protected:
    LinkType _node;    // ****** 链表的句柄,一个头节点的指针
public:
    // * 几个基本函数(构造,析构,拷贝构造,赋值运算符)
List() {
        EmptyInitialize();
    }
    List(SizeType n, const T& value) { FillInitialize(n, value); }
    // * 对只有一个数据成员的类,单参数的构造函数容易发生隐士转换,前面的explicit可以防止这个发生
    explicit List(SizeType n) { FillInitialize(n, T()); }
// * 用其他链表的任意一段区间构造一个新链表
    List(ConstIterator first, ConstIterator last) { RangeInitialize(first, last); };
    // * 用数组的任意一段区间构造一个新链表
    List(const T* first, const T* last) { RangeInitialize(first, last); }
    // * 用任意类型的数据区间构造一个新链表
#ifdef __STL_MEMBER_TEMPLATES
    template<class InputIterator>
    List(InputIterator first, InputIterator last) { RangeInitialize(first, last); }
#endif
    // * 拷贝构造
    List(const List<T> &x)
    {
        EmptyInitialize();
        Insert(Begin(), x.Begin(), x.End());
    }
~List()
    {
        Clear();
//delete _node;
        Destroy(_node);
        _node = NULL;
    }
/* * func: 赋值运算符重载 (传统写法) */
    //  List<T>& operator=(const List<T> &x)
    //  {
    //      if (this != &x)
    //      {
    //          Iterator first1 = Begin(), last1 = End();
    //          ConstIterator first2 = x.Begin(), last2 = x.End();
    //
    //          while (first1 != last1 && first2 != last2)
    //          {
    //              *first1++ = *first2++;
    //          }
    //
    //          if (first1 == last1)    // * 前面的链表先走到头,需要把x中剩下的节点拷贝到当前链表的最后
    //              Insert(last1, first2, last2);
    //          else
    //              Erase(first1, last1);
    //      }
    //
    //      return *this;
    //  }
/* * func: 赋值运算符重载 (简便写法) 简洁直观,但是不能避免自赋值 */
    List<T>& operator=(List<T> x)
    {
        Swap(x);
        return *this;
    }
public:
    // * List的对外接口
    Iterator Begin() { return Iterator((*_node)._next); }
    ConstIterator Begin() const { return Iterator((*_node)._next); }
Iterator End() { return Iterator(_node); }
    ConstIterator End() const { return Iterator(_node); }
  ReverseIterator RBegin() { return ReverseIterator(End()); }
    ConstReverseIterator RBegin()const { return ConstReverseIterator(End()); }
    ReverseIterator REnd() { return ReverseIterator(Begin()); }
    ConstReverseIterator REnd() const { return ConstReverseIterator(Begin()); }
bool Empty() { return _node->_next == _node; }
Reference Front() { return *Begin(); }
    ConstReference Front() const { return *Begin(); }
    Reference Back() { return *End(); }
    ConstReference Back() const { return *End(); }
    void Swap(List<T> &lt) { std::swap(_node, lt._node); }
// * List 基本操作的实现
    /* * func: 在position位置前插入值为x的节点 */
    Iterator Insert(Iterator &position, const T& x)
    {
        LinkType tmp = CreateNode(x);
    // * 该节点与前后节点接合
        tmp->_prev = position._node->_prev;
        tmp->_next = position._node;
        position._node->_prev = tmp;
        tmp->_prev->_next = tmp;
    // * 返回新的节点的迭代器
        return Iterator(tmp);
    }
    /* * func: 在position前面插入n个值为x的元素 */
    void Insert(Iterator &position, SizeType n, const T& x)
    {
        for (; n > 0; --n)
            Insert(position, x);
    }
    // * 函数体中把n强转成SizeType(size_t)类型的原因:如果不强转,会递归调用自己,因为不会退出,从而导致栈溢出
    //void Insert(Iterator &position, int n, const T& x) { Insert(position, (SizeType)n, x); }
    //void Insert(Iterator &position, long n, const T& x) { Insert(position, (SizeType)n, x); }
/* * func: 为用其他链表的一段区间去初始化链表而设计, 在position前插入 [first, last) 之间的元素 */
    void Insert(Iterator position, ConstIterator first, ConstIterator last)
    {
        for (; first != last; ++first)
            Insert(position, *first);
    }
/* * func: 为用数组初始化链表而设计 */
    void Insert(Iterator position, const T* first, const T* last)
    {
        for (; first != last; ++first)
            Insert(position, *first);
    }
/* * func: 为用任意类型的一段区间去初始化链表而设计 */
#ifdef __STL_MEMBER_TEMPLATES
    template<class InputIterator>
    void Insert(Iterator position, InputIterator first, InputIterator last)
    {
        for (; first != last; ++first)
            Insert(position, *first);
    }
#endif
    /* * func: 删除指定为位置position处的元素 */
    Iterator Erase(Iterator &position)
    {
        LinkType NextNode = position._node->_next;
        LinkType PrevNode = position._node->_prev;
        NextNode->_prev = PrevNode;
        PrevNode->_next = NextNode;
    // * 删除该节点
        //delete position._node;
        ListNodeAllocator::Deallocate(position._node);
    // * 返回该节点后一个节点的迭代器
        return Iterator(NextNode);
    }
/* * func: 删除指定区间 [first, last) 之间的元素 */
    Iterator Erase(Iterator &first, Iterator &last)
    {
        while (first != last)
            Erase(first++);
    return last;
    }
/* * func: 重新更改链表size到newSize,如果newSize 比 size大,后面补x*/
    void Resize(SizeType newSize, const ValueType& x)
    {
        SizeType len = 0;
        Iterator it = Begin();
        for (; it != End() && len < newSize; ++it, ++len)
            ;
        if (len == newSize)
            Erase(it, End());
        else
            Insert(End(), newSize - len, x);
    }
/* * func: 重新更改链表size到newSize */
    void Resize(SizeType newSize) { Resize(newSize, T()); }
    /* * func: 把list本身用[first, last)这段区间替换掉 */
    template<class InputIterator>
    void Assign(InputIterator first, InputIterator last)
    {
        Iterator it = Begin();
    // * 为了复用节点,首先把一些值赋给list开始的一段元素
        for (; it != End() && first != last; ++it, ++first)
            *it = *first;
        Erase(it, End());
       for (; first != last; ++first)
        Insert(it, *first);
    }
/* * func: 清空链表所有元素,但是不摧毁链表 */
    void Clear()
    {
        LinkType cur = _node->_next;
        LinkType del = NULL;
        while (cur != _node)    // * 依次删除除头节点以外的所
        {
            del = cur;
            cur = cur->_next;
            //delete del;
            ListNodeAllocator::Deallocate(del);
        }
        _node->_next = _node;
        _node->_prev = _node;
    }
    /* * func: 删除指定元素值的节点 */
    void Remove(const T& value)
    {
        Iterator cur = Begin();
        Iterator end = End();
        Iterator del;    // * 临时变量,记录要删除的节点
    while (cur != end)
        {
            if (*cur == value)    // * 注意迭代器失效的问题
            {
                del = cur;
                ++cur;
                Erase(del);
            }
            else
                ++cur;
        }
    }
    void Unique()
    {
        Iterator first = Begin();
        Iterator end = End();
        if (first == end) return;
        Iterator next = first;
        while (++next != end)
        {
            if (*first != *next)
                first = next;
            else
            {
                Erase(next);
                next = first;
            }
        }
    }
    /* * func: 把链表x合并到当前链表中 (不会创建新节点),当前链表与x合并之前都必须有序 */

    void Merge(List<T> &x)
    {
        Iterator first1 = Begin(), last1 = End();
        Iterator first2 = x.Begin(), last2 = x.End();
        Iterator next;
        while (first1 != last1 && first2 != last2)
        {
            if (*first2 < *first1)    // * first2的数据较小,需要合并
            {
                next = first2;
                Transfer(first1, first2, ++next);
                first2 = next;    // * 合并之后需要把first2指向x中的下一个节点(这时不能使用first2++,因为first2所指节点已经接到当前链表中了)
            }
            else
                ++first1;
        }  /* while */
        // * 到这里的情况有两种:first1还没走到头但first2到头了 或 first1与first2同时走到头; first1走到头了但first2还没走到头
        // * 对于第一种情况,无关紧要
        // * 对于第二种情况,要把x中剩余的节点接到当前链表的最后面
        if (first2 != last2)
            Transfer(last1, first2, last2);
    }
    /* * func: 对链表进行排序,主要使用单向快排 */
    void Sort()
    {
        _Sort(Begin(), End());
    }
    void Reverse()
    {
        Iterator first = Begin();        // * 第一个节点
        if (first._node == _node || first._node->_next == _node)  // * 没有节点或者只有一个节点,直接返回
            return;
        Iterator prev;        // * 临时变量,记录当前转接的第一
        Iterator end = End(); // * 循环的结束条件
        ++first;
        while (first != end)    // * first 从第二个数据节点开始
        {
            prev = first;
            ++first;
            Transfer(Begin(), prev, first);
        }
    }
    /* * func: 把链表x接合到当前的position位置前 */
    void Splice(Iterator &position, List<T> &x)
    {
        if (!x.Empty())
            Transfer(position, x.Begin(), x.End());
    }
    /* * func: 把i所指节点接到position前面的位置 */
    void Splice(Iterator &position, Iterator i)
    {
        Iterator j = i;
        ++j;
        // * 自己接到自己前面,或者前一个节点接到当前节点的前面,直接
        if (position == i || position == j)
            return;
        Transfer(position, i, j);
    }
    /* * func: 把 [first, last) 所指区间接到position前面 */
    void Splice(Iterator &position, Iterator first, Iterator last)
    {
        if (first != last)
            Transfer(position, first, last);
    }
    void PushFront(const T& x) { Insert(Begin(), x); }
    void PushBack(const T& x) { Insert(End(), x); }
    void PopFront() { Erase(Begin()); }
    void PopBack() { Erase(--End()); }
protected:
    // * List的几个内部接口
    /* * func: 申请一个节点的内存,并调用节点的构造函数,最后返回该节点的指针 */
    LinkType CreateNode(const T& value)
    {
        LinkType tmp = GetNode();
        Construct(tmp, value);
        return tmp;
    }
    /* * func: 申请一个链表节点的空间(只申请空间并不构造) */
    LinkType GetNode()
    {
        return ListNodeAllocator::Allocate();
    }
    /* * func: 初始化空的链表 (其实就是构造一个头节点) */
    void EmptyInitialize()
    {
        _node = CreateNode(T());
        _node->_next = _node;
        _node->_prev = _node;
    }
    /* * func: 构造函数用 */
    void FillInitialize(SizeType n, const T& value)
    {
        EmptyInitialize();
        Insert(Begin(), n, value);
    }
    /* * func: 把[first, last)内的所有元素移动到position之前 */
    // *ps: 区间不可重叠,即position不能位于[first, last)区间内部
    void Transfer(Iterator position, Iterator first, Iterator last)
    {
        if (position != last)
        {
            // * 总共有三处指针(总共6个)需要修改
            // * 三个向右的方向
            last._node->_prev->_next = position._node;
            position._node->_prev->_next = first._node;
            first._node->_prev->_next = last._node;
            // * 三个向左的方向
            LinkType tmp = position._node->_prev;
            position._node->_prev = last._node->_prev;
            last._node->_prev = first._node->_prev;
            first._node->_prev = tmp;
        }
    }
    void RangeInitialize(ConstIterator first, ConstIterator last)
    {
        EmptyInitialize();
        Insert(Begin(), first, last);
    }
    void RangeInitialize(const T* first, const T* last)
    {
        EmptyInitialize();
        Insert(Begin(), first, last);
    }
    #ifdef __STL_MEMBER_TEMPLATES
    template<class InputIterator>
    void RangeInitialize(InputIterator first, InputIterator last)
    {
        EmptyInitialize();
        Insert(Begin(), first, last);
    }
#endif
    void _Sort(Iterator first, Iterator last)
    {
        Iterator tmp = first;
        if (tmp == last || ++tmp == last)
            return;
        Iterator mid = first;
        Iterator cur = first;
        ValueType key = *cur;
        ++cur;
        while (cur != last)
        {
            if (*cur < key)
            {
                if (++mid != cur)
                    std::swap(*cur, *mid);
            }
            ++cur;
        }
        std::swap(*first, *mid);
        _Sort(first, mid);
        _Sort(++mid, last);
    }
};
// * 几个全局函数
template<class T>
inline bool operator==(const List<T> &x, const List<T> &y)
{
    typedef typename List<T>::LinkType LinkType;
    LinkType end1 = x._node;
    LinkType end2 = y._node;
    LinkType f1 = end1->_next;
    LinkType f2 = end2->_next;
    for (; f1 != end1 && f2 != end2; f1 = f1->_next, f2 = f2->_next)
    {
        if (f1->_data != f2->_data)
            return false;
    }
    // ****** 循环结束后还不能直接返回真,这时要看两个链表是不是一样
    return f1 == end1 && f2 == end2;
}
template<class T>
inline bool operator<(const List<T> &x, const List<T> &y)
{
return true;
}
template<class T>
inline void Swap(const List<T> &x, const List<T> &y)

{
    x.Swap(y);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值