IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构算法与应用-C++语言描述 circularArrayList (待解决) -> 正文阅读

[数据结构与算法]数据结构算法与应用-C++语言描述 circularArrayList (待解决)

circularArrayList.cpp

#include <iostream>
#include <sstream>
#include <algorithm>
#include <iterator>

//数据结构算法与应用-C++语言描述 circularArrayList

//ex31. 假设用公式 ( 5-3 ) 来表示线性表。分别用变量 first 和 last 表示线性表首元素和尾元素的
//      位置。
//      1 ) 开发一个类 circularArrayList,它与 circularArrayList 类似。实现所有的方法。在删除和插人方
//      法中,对位于删除或插和人元素的左面或右面的元素,有选择地决定向左移动或向右移
//      动,以此提高方法的性能。
//      2 ) 计算每一个方法的复杂度。
//      3 ) 测试你的代码。


using namespace std;
//线性表一数组

//抽象数据类型
template<class T>
class linearList
{
public:
    virtual ~linearList() {}
    //返回true,当且仅当线性表为空
    virtual bool empty() const = 0;
    //返回线性表的元素个数
    virtual int size() const = 0;
    //返回索引为 theIndex 的元素
    virtual T &get(int theIndex) const = 0;
    //返回元素 theElement 第一次出现时的索引
    virtual int indexOf(const T &theElement) const = 0;
    //删除索引为 theIndex 的元素
    virtual void erase(int theIndex) = 0;
    //把 theElement 插入线性表中索引为 theIndex 的位置上
    virtual void insert(int theIndex, const T &theElement) = 0;
    //把线性表插入输出流 out
    virtual void output(ostream &out) const = 0;
};

template<class T>
void circularCopy(T *start, T *end, T *initial, int arrayLength, T *dest)
{
    int size = end - start;
    size = size >= 0 ? size : size + arrayLength;
    for (int i = 0; i < size; i++)
    {
        dest[i] = *(initial + ((i + (start - initial)) % arrayLength));
    }
}


//改变一个一维数组长度
template<class T>
void changeLength1D(T *&a, int oldLength, int newLength)
{
    if (newLength < 0)
        throw logic_error("new length must be >= 0");

    //新数组
    T *temp = new T[newLength];

    //需要复制的元素个数
    int number = min(oldLength, newLength);
    copy(a, a + number, temp);

    //释放老数组的内存空间
    delete [] a;
    a = temp;
}



//circularArrayList 的类定义
template<class T>
class circularArrayList : public linearList<T>
{
public:
    //构造函数,复制构造函数和析构函数
    circularArrayList(int initialCapacity = 10);
    circularArrayList(const circularArrayList<T> &);
    ~circularArrayList() {delete[] element;}

    //ADT 方法
    bool empty() const override { return listSize == 0; }
    int size() const override { return listSize; }
    T &get(int theIndex) const override;
    int indexOf(const T &theElement) const override;
    void erase(int theIndex) override;
    void insert(int theIndex, const T &theElement) override;
    void output(ostream &out) const override;

    //其他方法
    int capacity() const { return arrayLength; }
    //ex5. 编写一个方法 circularArrayList<T>::trimToSize,它使数组的长度等于 max{listSize,1}。
    //这个方法的复杂度是多少?” 测试你的代码。
    circularArrayList<T> &trimToSize();

    //ex6. 编写方法 circularArrayList<T>::setSize,它使线性表的大小等于指定的大小。若线性表开始的大小
    //小于指定的大小,则不增加元素。若线性表开始的大小大于指定的大小,则删除多余的元
    //素。这个方法的复杂度是多少? 测试你的代码。
    circularArrayList<T> &setSize(int length);

    //ex7. 重载操作符[],使得表达式 x加返回对线性表第i个元素的引用。
    //若线性表没有第i个元则抛出异常语句 x[i]=y 和 y= x[i]] 按以往预期的方式执行。
    //测试你的代码。
    T &operator[](int i);

    //ex8. 重载操作符 ==,使得表达式 x==y 返回 true,当上且仅当两个用数组描述的线性表x
    //和y 相等(即对所有的 i,两个线性表的第i 个元素相等 )。测试你的代码。
    bool operator==(const circularArrayList<T> &right) const;

    //ex9.
    bool operator!=(const circularArrayList<T> &right) const;

    //ex10. 重载操作符 <,使得表达式 x<y 返回 true,当且仅当用数组描述的线性表 x 按字典顺序小
    //于用数组描述的线性表v ( 见练习 8 )。测试你的代码。
    bool operator<(const circularArrayList<T> &right) const;

    //ex11. 编写方法 circularArrayList<T>::push_back,它把元素 theElement 插到线性表的右端。不要利用
    //insert 方法。方法的时间复杂度是多少?测试你的代码。
    void push_back(const T &theElement);

    //ex12. 编写方法 circularArrayList<T>::pop_back,它把线性表右端的元素删除。不要利用 erase 方法。方
    //法的时间复杂度是多少? 测试你的代码。
    T &pop_back();

    //ex13. 编写方法 circularArrayList<T>::swap(theLisb,它交换线性表的元素 *this 和 theList。方法的时间
    //复杂度是多少? 测试你的代码。
    circularArrayList<T> &swap(circularArrayList<T> &theList);

    //ex14. 编写方法 circularArrayList<T>::reserve(theCapacity),它把数组的容量改变为当前容量和 theCapacity
    //的较大者。测试你的代码。
    circularArrayList<T> &reserve(int theCapacity);

    //ex15. 编写方法 circularArrayList<T>::set(theIndex,theElement),它用元素 theElement 替换索引为 theIndex
    //的元素。若索引 theIndex 超出范围,则抛出异常。返回原来索引为 theIndex 的元素。测试
    //你的代码。
    T set(int theIndex, const T &theElement);

    //ex16. 编写方法 circularArrayList<T>::clear,它使线性表为空。方法的复杂度是多少?” 测试你的代码。
    circularArrayList<T> &clear();

    //ex17. 编写方法 circularArrayList<T>::removeRange,它删除指定索引范围内的所有元素。方法的复杂度
    //是多少?测试你的代码。
    circularArrayList<T> &removeRange(int startIndex, int endIndex);

    //ex18. 编写方法 circularArrayList<T>::lastInexOf,它的返回值是指定元素最后出现时的索引。如果这样
    //的元素不存在,则返回 -1。方法的复杂度是多少? 测试你的代码。
    int lastIndexOf(const T &theElement) const;

    //ex20. 类 circularArrayList ( 程序 5-1 ) 的缺点是,它不减少数组 element 的长度。
    //1: 编写类 circularArrayList 的一个新版本。如果在删除之后,线性表的大小降至 arrayLength/4 以
    //  下,就创建一个新的数组,长度为 max{arrayLength/2,initialCapacity}。然后将老表
    //  中的元素复制到新表。
    //2 ( 选择性练习 ) 从空表开始,考察大小为地的线性表的操作序列。假设当初始容量等于
    //  或超过线性表大小的最大值时,总的执行步数是f(n)。证明,如果起始容量为1,而且
    //  在插入和删除操作中,可以按照上面和 5.3 节所述的方式改变数组长度,那么执行步
    //  数最多为 cf(n),其中 c 是某个常数。
    circularArrayList<T> &decreaseArray(int capacity);

    ///ex33. 1 ) 编写方法 circularArrayList<T>::reverse,它原地颠倒线性表元素的顺序 ( 即在数组 element 中
    //      完成操作,不创建新的数组 )。颠倒顺序之前,线性表的第 k 个元素是 element[k],站
    //      倒之后,线性表的第 k 个元素是 element[listSize-k-1]。不要利用 STL 函数 reverse。
    //      2 ) 方法应具有 listSize 的线性复杂度。证明这个性能。
    //      3 ) 设计测试数据,测试方法的正确性。
    //      4 ) 编写另一个原地颠倒 circularArrayList 对象的方法。它不是 circularArrayList 的成员函数,不能访问
    //      circularArrayList 的数据成员。不过,这个方法可以调用 circularArrayList 的成员函数。
    //      5 ) 计算方法的复杂度
    //      6 ) 使用大小分别为 1000、5000 和 10 000 的线性表,比较两个颠倒顺序算法的运行时间
    circularArrayList<T> &reverse();

    //ex23.1) 编写方法 circularArrayList<T>::leftShift(i),它将线性表的元素向左移动i个位置。如果
    //      x=[0,1,2,3,4],那么 x.leftShift(2) 的结果是 x=[2,3,4]。
    //      2 ) 计算方法的复杂度。
    //      3 ) 测试你的代码-
    circularArrayList<T> &leftShift(int shift);

    //ex24. 在一个循环移动的操作中,线性表的元素根据给定的值,按顺时针方向移动。例如,
    //x=[0,1,2,3,4],循环移动 2 的结果是 x=[2,3,4,0,1]。
    //      1 ) 描述一下如何利用 3 次逆转操作完成循环移动。每一次逆转操作都可以将线性表的一
    //      部分或全部逆转。
    //      2 ) 编写方法 circularArrayList<T>::circularShiftt),它将线性表的元素循环移动i个位置。方法应
    //      具有线性表长度的线性复杂度。
    //      3 ) 测试你的代码。
    circularArrayList<T> &circularShift(int shift);

    //ex25. 调用语句 x.half,可以将 x 的元素隔一个删除一个。如果 xsize() 是 7, xelement[]=[2,13,4.5,17,8,29],
    //      那么 x.half() 的结果是 x.size() 是 4,x.element[]=[2,4.17,9]。如果 x.size() 是 4,x.element[]=[2,13,4.5],
    //      那么 x.half() 的结果是 x.size() 是 2,x.element[]=[2,4]。如果 x 为空,那么 x.half() 的结果也是X 为空。
    //      1 ) 编写方法 circularArrayList<T>::half()。不能利用类 circularArrayList 的其他方法。复杂度应该为O(listSize)
    //      2 ) 证明方法的复杂度为 O(listSize)。
    //      3 ) 测试你的代码。
    circularArrayList<T> &half();

    ///ex34.令 a 和b 是类 circularArrayList 的两个对象。
    //      1 ) 编写方法 circularArrayList<T>::meld(ab),它生成一个新的线性表,从 a 的第 0 个元素开始,
    //      交替地包含a 和 b的元素。如果一个表的元素取完了,就把另一个表的剩余元素附加
    //      到新表中。调用语句 c.meld(a,b) 使 成为合并后的表。方法应具有两个输入线性表大
    //      小的线性复杂度。
    //      2 ) 证明方法具有 a 和b 大小之和的线性复杂度。
    //      3 ) 测试你的代码。

    circularArrayList<T> &meld(circularArrayList<T> &a, circularArrayList<T> &b);

    ///ex35.令a 和b 是类 circularArrayList 的两个对象。假设它们的元素从左到右非递减有序。
    //      1 ) 编写方法 circularArrayList<T>::merge(a,b),它生成一个新的有序线性表,包含a 和 的所有元
    //      素。归并后的线性表是调用对象 *this。不要利用 STL 本数 merge。
    //      2 ) 计算方法的复杂度。
    //      3 ) 测试你的代码。
    circularArrayList<T> &merge(circularArrayList<T> &a, circularArrayList<T> &b);

    ///ex36. 1 ) 编写方法 circularArrayList<T>::split(lab),它生成两个线性表a 和b。a 包含 *this 中索引为偶
    //      数的元素,b 包含其余的元素。
    //    2 ) 计算方法的复杂度。
    //    3 ) 测试你的代码。
    circularArrayList<T> &split(circularArrayList<T> &a, circularArrayList<T> &b);
public:
    class iterator
    {
    public:
        // C++ 的typedef 语句实现双向迁代器
        typedef bidirectional_iterator_tag iterator_category;
        typedef T value_type;
        typedef ptrdiff_t difference_type;
        typedef T *pointer;
        typedef T &reference;

        //构造函数
        iterator(T *thePosition = 0) { position = thePosition; }

        //解引用操作符
        T &operator*() const { return *position; }
        T *operator->() const { return &*position; }


        //迭代器的值增加
        iterator &operator++() //前加
        {
            ++position;
            return *this;
        }
        iterator operator++(int) //后加
        {
            iterator old = *this;
            ++position;
            return old;
        }

        //迭代器的值减少
        iterator &operator--() //前减
        {
            --position;
            return *this;
        }

        iterator operator--(int) //后减
        {
            iterator old = *this;
            --position;
            return old;
        }

        //测试是否相等
        bool operator!=(const iterator right) const
        {
            return position != right.position;
        }

        bool operator==(const iterator right) const
        {
            return position == right.position;
        }
        //27. 扩展迭代器类 circularArrayList::iterator ( 程序 5-11 ),使得它成为随机访问迭代器。利用 STL 的
        //    排序函数对一个线性表排序,以测试这个和迭代器类。
        T &operator[](int i)
        {
            return *(position + i);
        }

        ptrdiff_t operator-(const circularArrayList<T>::iterator &right) const
        {
            return position - right.position;
        }

        T &operator-(const ptrdiff_t &diff) const
        {
            return *(position - diff);
        }

        T &operator+(const ptrdiff_t &diff) const
        {
            return *(position + diff);
        }

    protected:
        T *position; //指向表元素的指针
    };

    iterator begin() { return iterator(element); }
    iterator end() { return iterator(element + listSize); }

protected:
    //索引 theIndex 无效,则抛出异常
    void checkIndex(int theIndex) const;
    //改变容量大小
    void changeArraySize(int capacity);
    //扩容
    void increaseArray(int capacity);

    //存储线性表元素的一维数组
    T *element = NULL;
    //一维数组的容量
    int arrayLength = 0;
    //线性表的元素个数
    int listSize = 0;
    //初始容量
    int initialCapacity = 10;
    //起始位置
    int first = 0;
    //最后位置
    int last = 0;
};

//类 circularArrayList 的构造函数
template<class T>
circularArrayList<T>::circularArrayList(int initialCapacity)
{
    //构造函数
    if (initialCapacity < 1)
    {
        ostringstream s;
        s << "Initial capacity = " << initialCapacity << " must be > 0";
        throw logic_error(s.str());
    }
    arrayLength = initialCapacity;
    initialCapacity = initialCapacity;
    element = new T[arrayLength];
    listSize = 0;
    first = 0;
    last = 0;
}

template<class T>
circularArrayList<T>::circularArrayList(const circularArrayList<T> &theList)
{
    //复制构造函数
    arrayLength = theList.arrayLength;
    initialCapacity = theList.initialCapacity;
    listSize = theList.listSize;
    element = new T[arrayLength];
    circularCopy(theList.element + theList.first, theList.element + theList.last + 1, theList.element, theList.arrayLength, element);
    first = 0;
    last = listSize;
}

//方法 checkIndex的时间复杂度是 (1),
template<class T>
void circularArrayList<T>::checkIndex(int theIndex) const
{
    //确定索引theIndex在0 和 listSize - 1之间
    if (theIndex < 0 || theIndex >= listSize)
    {
        //字符串输出流对象
        ostringstream s;
        s << "index = " << theIndex << " size = " << listSize;
        throw logic_error(s.str());
    }
}

//方法 get的时间复杂度是 (1),
template<class T>
T &circularArrayList<T>::get(int theIndex) const
{
    //返回索引为 theIndex 的元素
    //若此元素不存在,则抛出异常
    checkIndex(theIndex);
    return element[theIndex];
}

//indexOf 的时间复杂度是 O(max{listSize,1})
template<class T>
int circularArrayList<T>::indexOf(const T &theElement) const
{
    for (int i = 0; i < listSize; i++)
    {
        if (element[(i + first) % arrayLength] == theElement)
        {
            return i;
        }
    }
    return -1;
}

/*
 删除一个元素为了从线性表中删除索引为 theIndex 的元素,
 首先要确定线性表包含这个元素,然后删除这个元素。
 若没有这个元素,则抛出类型为异常

 如果没有索引 theIndex 的元素,
 就抛出异常,erase 时间复杂度是 O(1)。如果有这个元素,
 那么要移动的元素个数是 listSize-theIndex
 时间复杂度是 O(listSize-theIndex)
*/
template<class T>
void circularArrayList<T>::erase(int theIndex)
{
    //删除其索引为 theIndex 的元素
    //如果该元素不存在,则抛出异常
    checkIndex(theIndex);
    if (theIndex >= (listSize + 1) / 2)
    {
        for (int i = theIndex; i < listSize - 1; i++)
        {
            element[(i + first) % arrayLength] = element[(i + first + 1) % arrayLength];
        }
        element[last - 1].~T();
        last--;
        last = (last + arrayLength) % arrayLength;
    }
    else
    {
        for (int i = theIndex; i > 0; i--)
        {
            element[(i + first) % arrayLength] = element[(i + first - 1 + arrayLength) % arrayLength];
        }
        element[first].~T();
        first++;
        first %= arrayLength;
    }

    listSize--;
    if (listSize < arrayLength / 4)
        decreaseArray(arrayLength / 2);
}


template<class T>
void circularArrayList<T>::insert(int theIndex, const T &theElement)
{
    //在索引 theIndex 处插入元素 theElement
    //确定索引theIndex在0 和 listSize 之间
    if (theIndex < 0 || theIndex > listSize)
    {
        //字符串输出流对象
        ostringstream s;
        s << "index = " << theIndex << " size = " << listSize;
        throw logic_error(s.str());
    }

    //有效索引,确定数组是否已满
    if (listSize == arrayLength - 1)
    {
        //数组空间已满,数组长度倍增
 		increaseArray(2 * arrayLength);
    }

    //把元素向后移动
   	if(theIndex >= (listSize + 1) / 2)
   	{
   		for(int i = listSize; i > theIndex; i--)
   		{
            element[(i + first) % arrayLength] = element[(i + first - 1 + arrayLength) % arrayLength];
   		}
        last++;
        last %= arrayLength;
   	}
   	else //把元素向前移动
   	{
        for(int i = 0; i < theIndex; i++)
        {
            element[(i + first - 1 + arrayLength) % arrayLength] = element[(i + first) % arrayLength];
        }
        first--;
        first = (first + arrayLength) % arrayLength;
   	}
   	
    element[(theIndex + first) % arrayLength] = theElement;
    listSize++;
}

//输出函数 output 和重载 <<
template<class T>
void circularArrayList<T>::output(ostream &out) const
{
    //把线性表插入输出流
    for (int i = 0; i < listSize; i++)
    {
        cout<< element[(i + first) % arrayLength] << " ";
    }
}

//重载 <<
template<class T>
ostream &operator<<(ostream &out, const circularArrayList<T> &x)
{
    x.output(out);
    return out;
}

//扩容
template<class T>
void circularArrayList<T>::increaseArray(int capacity)
{
    if (capacity <= arrayLength)
    {
        cout << "input capacity <= arrayLength";
        return;
    }
    changeArraySize(capacity);
    arrayLength = capacity;
}


//ex5. 编写一个方法 circularArrayList<T>::trimToSize,它使数组的长度等于 max{listSize,1}。
//这个方法的复杂度是多少?” 测试你的代码。
template<class T>
circularArrayList<T> &circularArrayList<T>::trimToSize()
{
    if (listSize == arrayLength) return *this;
    int oldLength = arrayLength;
    arrayLength = max(listSize, 1);
    changeLength1D(element, oldLength, arrayLength);
    return *this;
}

//ex6. 编写方法 circularArrayList<T>::setSize,它使线性表的大小等于指定的大小。若线性表开始的大小
//小于指定的大小,则不增加元素。若线性表开始的大小大于指定的大小,则删除多余的元
//素。这个方法的复杂度是多少? 测试你的代码。
template<class T>
circularArrayList<T> &circularArrayList<T>::setSize(int length)
{
    if (length < 0 || length > listSize)
        return *this;
    listSize = length;
    return *this;
}

//ex7. 重载操作符[],使得表达式 x加返回对线性表第i个元素的引用。
//若线性表没有第i个元则抛出异常语句 x[i]=y 和 y= x[i] 按以往预期的方式执行。
//测试你的代码。
template<class T>
T &circularArrayList<T>::operator[](int i)
{
    checkIndex(i);
    return element[i];
}

//ex8. 重载操作符 ==,使得表达式 x==y 返回 true,当上且仅当两个用数组描述的线性表x
//和y 相等(即对所有的 i,两个线性表的第i 个元素相等 )。测试你的代码。
template<class T>
bool circularArrayList<T>::operator==(const circularArrayList<T> &right) const
{
    if (right.listSize != listSize) return false;
    for (int i = 0; i < listSize; i++)
    {
        if (element[i] != right.element[i]) return false;
    }
    return true;
}

//ex9.
template<class T>
bool circularArrayList<T>::operator!=(const circularArrayList<T> &right) const
{
    if (*this == right)
    {
        return false;
    }
    else
    {
        return true;
    }
}

//ex10. 重载操作符 <,使得表达式 x<y 返回 true,当且仅当用数组描述的线性表 x 按字典顺序小
//于用数组描述的线性表v ( 见练习 8 )。测试你的代码。
template<class T>
bool circularArrayList<T>::operator<(const circularArrayList<T> &right) const
{
    int minSize = min(size(), right.size());

    for (int i = 0; i < size(); i++)
    {
        if (element[i] < right.element[i]) return true;
    }
    if (size() < right.size()) return true;
    return false;
}

//ex11. 编写方法 circularArrayList<T>::push_back,它把元素 theElement 插到线性表的右端。不要利用
//insert 方法。方法的时间复杂度是多少?测试你的代码。
template<class T>
void circularArrayList<T>::push_back(const T &theElement)
{
    if (arrayLength == listSize)
        increaseArray(2 * arrayLength);
    element[listSize++] = theElement;
}

//ex12. 编写方法 circularArrayList<T>::pop_back,它把线性表右端的元素删除。不要利用 erase 方法。方
//法的时间复杂度是多少? 测试你的代码。
template<class T>
T &circularArrayList<T>::pop_back()
{
    if (listSize == 0)
    {
        throw logic_error("circularArrayList is empty");
    }
    T &theElement = element[--listSize];

    if (listSize < arrayLength / 4)
        decreaseArray(arrayLength / 2);

    return theElement;
}

//ex13. 编写方法 circularArrayList<T>::swap(theLisb,它交换线性表的元素 *this 和 theList。方法的时间
//复杂度是多少? 测试你的代码。
template<class T>
circularArrayList<T> &circularArrayList<T>::swap(circularArrayList<T> &theList)
{
    std::swap(listSize, theList.listSize);
    std::swap(arrayLength, theList.arrayLength);
    std::swap(element, theList.element);
    return *this;
}

//ex14. 编写方法 circularArrayList<T>::reserve(theCapacity),它把数组的容量改变为当前容量和 theCapacity
//的较大者。测试你的代码。
template<class T>
circularArrayList<T> &circularArrayList<T>::reserve(int theCapacity)
{
    if (theCapacity <= arrayLength) return *this;
    changeLength1D(element, arrayLength, theCapacity);
    arrayLength = theCapacity;
    return *this;
}

//ex15. 编写方法 circularArrayList<T>::set(theIndex,theElement),它用元素 theElement 替换索引为 theIndex
//的元素。若索引 theIndex 超出范围,则抛出异常。返回原来索引为 theIndex 的元素。测试
//你的代码。
template<class T>
T circularArrayList<T>::set(int theIndex, const T &theElement)
{
    checkIndex(theIndex);
    T tmp = element[theIndex];
    element[theIndex] = theElement;
    return tmp;
}

//ex16. 编写方法 circularArrayList<T>::clear,它使线性表为空。方法的复杂度是多少?” 测试你的代码。
template<class T>
circularArrayList<T> &circularArrayList<T>::clear()
{
    for (int i = 0; i < size(); i++)
    {
        element[i].~T();
    }
    listSize = 0;
    decreaseArray(initialCapacity);
    arrayLength = initialCapacity;
    return *this;
}

//ex17. 编写方法 circularArrayList<T>::removeRange,它删除指定索引范围内的所有元素。方法的复杂度
//是多少?测试你的代码。
template<class T>
circularArrayList<T> &circularArrayList<T>::removeRange(int startIndex, int endIndex)
{
    checkIndex(startIndex);
    checkIndex(endIndex);
    int count = endIndex - startIndex + 1;
    copy(element + endIndex, element + listSize, element + startIndex);

    for (int i = startIndex + count; i < listSize; i++)
        element[i].~T();

    listSize -= count;

    if (listSize < arrayLength / 4)
    {
        decreaseArray(arrayLength / 2);
    }
    return *this;
}

//ex18. 编写方法 circularArrayList<T>::lastInexOf,它的返回值是指定元素最后出现时的索引。如果这样
//的元素不存在,则返回 -1。方法的复杂度是多少? 测试你的代码。
template<class T>
int circularArrayList<T>::lastIndexOf(const T &theElement) const
{
    for (int i = listSize - 1; i >= 0; i--)
    {
        if (element[i] == theElement)
            return i;
    }
    return -1;
}


//ex20. 类 circularArrayList ( 程序 5-1 ) 的缺点是,它不减少数组 element 的长度。
//1: 编写类 circularArrayList 的一个新版本。如果在删除之后,线性表的大小降至 arrayLength/4 以
//  下,就创建一个新的数组,长度为 max{arrayLength/2,initialCapacity}。然后将老表
//  中的元素复制到新表。
//2 ( 选择性练习 ) 从空表开始,考察大小为地的线性表的操作序列。假设当初始容量等于
//  或超过线性表大小的最大值时,总的执行步数是f(n)。证明,如果起始容量为1,而且
//  在插入和删除操作中,可以按照上面和 5.3 节所述的方式改变数组长度,那么执行步
//  数最多为 cf(n),其中 c 是某个常数。
template<class T>
circularArrayList<T> &circularArrayList<T>::decreaseArray(int capacity)
{
    if (capacity > arrayLength || capacity < 0) 
    {
    	cout<<"capacity > arrayLength || capacity < 0"<<endl;
    	return *this;
    }
    if (capacity < initialCapacity) capacity = initialCapacity;
    if (capacity == arrayLength) 
    {
    	cout<<"capacity > arrayLength || capacity < 0"<<endl;
		return *this;
    }
    changeArraySize(capacity);
    return *this;
}


///ex33. 1 ) 编写方法 circularArrayList<T>::reverse,它原地颠倒线性表元素的顺序 ( 即在数组 element 中
//      完成操作,不创建新的数组 )。颠倒顺序之前,线性表的第 k 个元素是 element[k],站
//      倒之后,线性表的第 k 个元素是 element[listSize-k-1]。不要利用 STL 函数 reverse。
//      2 ) 方法应具有 listSize 的线性复杂度。证明这个性能。
//      3 ) 设计测试数据,测试方法的正确性。
//      4 ) 编写另一个原地颠倒 circularArrayList 对象的方法。它不是 circularArrayList 的成员函数,不能访问
//      circularArrayList 的数据成员。不过,这个方法可以调用 circularArrayList 的成员函数。
//      5 ) 计算方法的复杂度
//      6 ) 使用大小分别为 1000、5000 和 10 000 的线性表,比较两个颠倒顺序算法的运行时间
template<class T>
circularArrayList<T> &circularArrayList<T>::reverse()
{
    for (int i = 0; i < listSize / 2; i++)
    {
//        std::swap(element[i], element[listSize - i - 1]);
        std::swap(element[(i + first) % arrayLength], element[(listSize - i - 1 + arrayLength) % arrayLength]);
    }
    return *this;
}

//ex23.1) 编写方法 circularArrayList<T>::leftShift(i),它将线性表的元素向左移动i个位置。如果
//      x=[0,1,2,3,4],那么 x.leftShift(2) 的结果是 x=[2,3,4]。
//      2 ) 计算方法的复杂度。
//      3 ) 测试你的代码-
template<class T>
circularArrayList<T> &circularArrayList<T>::leftShift(int shift)
{
    if (shift < 0 || shift > listSize)
    {
        ostringstream s;
        s << "shift shift < 0 || shift > listSize";
        throw logic_error(s.str());
    }

    copy(element + shift, element + listSize, element);
    listSize -= shift;

    for (int i = listSize - shift; i < listSize; i++)
    {
        element[i].~T();
    }

    if (listSize < arrayLength / 4)
    {
        changeLength1D(element, arrayLength, arrayLength / 2);
    }

    return *this;
}

//ex24. 在一个循环移动的操作中,线性表的元素根据给定的值,按顺时针方向移动。例如,
//x=[0,1,2,3,4],循环移动 2 的结果是 x=[2,3,4,0,1]。
//      1 ) 描述一下如何利用 3 次逆转操作完成循环移动。每一次逆转操作都可以将线性表的一
//      部分或全部逆转。
//      2 ) 编写方法 circularArrayList<T>::circularShiftt),它将线性表的元素循环移动i个位置。方法应
//      具有线性表长度的线性复杂度。
//      3 ) 测试你的代码。
template<class T>
circularArrayList<T> &circularArrayList<T>::circularShift(int shift)
{
    if (shift < 0)
    {
        ostringstream s;
        s << "circularShift shift < 0";
        throw logic_error(s.str());
    }

    shift %= listSize;

    reverse();
    std::reverse(element, element + listSize - shift);
    std::reverse(element + listSize - shift, element + listSize);
    return *this;
}

//ex25. 调用语句 x.half,可以将 x 的元素隔一个删除一个。如果 xsize() 是 7, xelement[]=[2,13,4.5,17,8,29],
//      那么 x.half() 的结果是 x.size() 是 4,x.element[]=[2,4.17,9]。如果 x.size() 是 4,x.element[]=[2,13,4.5],
//      那么 x.half() 的结果是 x.size() 是 2,x.element[]=[2,4]。如果 x 为空,那么 x.half() 的结果也是X 为空。
//      1 ) 编写方法 circularArrayList<T>::half()。不能利用类 circularArrayList 的其他方法。复杂度应该为O(listSize)
//      2 ) 证明方法的复杂度为 O(listSize)。
//      3 ) 测试你的代码。
template<class T>
circularArrayList<T> &circularArrayList<T>::half()
{
    if (listSize <= 1) return *this;

    for (int i = 1; i < (listSize + 1) / 2; i++)
    {
        element[i] = element[i * 2];
    }

    int oldSize = listSize;
    listSize = (listSize + 1) / 2;

    for (int i = listSize; i < oldSize; i++)
    {
        element[i].~T();
    }

    if (listSize < arrayLength / 4)
    {
        changeLength1D(element, arrayLength, arrayLength / 2);
    }
    return *this;
}

///ex34.令 a 和b 是类 circularArrayList 的两个对象。
//      1 ) 编写方法 circularArrayList<T>::meld(ab),它生成一个新的线性表,从 a 的第 0 个元素开始,
//      交替地包含a 和 b的元素。如果一个表的元素取完了,就把另一个表的剩余元素附加
//      到新表中。调用语句 c.meld(a,b) 使 成为合并后的表。方法应具有两个输入线性表大
//      小的线性复杂度。
//      2 ) 证明方法具有 a 和b 大小之和的线性复杂度。
//      3 ) 测试你的代码。

template<class T>
circularArrayList<T> &circularArrayList<T>::meld(circularArrayList<T> &a, circularArrayList<T> &b)
{
    if (a.listSize == 0 && b.listSize == 0) return *this;
    int minSize = a.listSize < b.listSize ? a.listSize : b.listSize;
    int maxSize = a.listSize > b.listSize ? a.listSize : b.listSize;
    int newLength = a.listSize > b.listSize ? a.arrayLength : b.arrayLength;
    circularArrayList<T>* maxList = a.listSize > b.listSize ? &a : &b;

    if (maxSize + minSize > arrayLength)
    {
        newLength = a.arrayLength + b.arrayLength;
    }
    increaseArray(newLength);
    listSize = maxSize + minSize;
    for (int i = 0; i < minSize; i++)
    {
        element[i * 2] = a.element[(i + a.first) % a.arrayLength];
        element[i * 2 + 1] = b.element[(i + b.first) % b.arrayLength];
    }
    for (int i = minSize; i < maxSize; i++)
    {
        element[minSize + i] = maxList->element[(i + maxList->first) % maxList->arrayLength];
    }
    return *this;
}

///ex35.令a 和b 是类 circularArrayList 的两个对象。假设它们的元素从左到右非递减有序。
//      1 ) 编写方法 circularArrayList<T>::merge(a,b),它生成一个新的有序线性表,包含a 和 的所有元
//      素。归并后的线性表是调用对象 *this。不要利用 STL 本数 merge。
//      2 ) 计算方法的复杂度。
//      3 ) 测试你的代码。
template<class T>
circularArrayList<T> &circularArrayList<T>::merge(circularArrayList<T> &a, circularArrayList<T> &b)
{
    if (a.listSize == 0 && b.listSize == 0) return *this;
    int minSize = a.listSize < b.listSize ? a.listSize : b.listSize;
    int maxSize = a.listSize > b.listSize ? a.listSize : b.listSize;
    int newLength = a.listSize > b.listSize ? a.arrayLength : b.arrayLength;
    if (minSize == 0) return *this;

    if (maxSize + minSize > arrayLength)
    {
        newLength = a.arrayLength + b.arrayLength;
    }
    listSize = maxSize + minSize;
    increaseArray(newLength);
    int index = 0, aindex = 0, bindex = 0;
    cout << listSize << endl;
    for (int i = 0; i < listSize; i++)
    {
        if (aindex < a.size() && bindex < b.size())
        {
            if (a.element[(aindex + a.first) % a.arrayLength] <= b.element[(bindex + b.first) % b.arrayLength])
                element[index] = a.element[((aindex++) + a.first) % a.arrayLength];
            else
                element[index] = b.element[((bindex++) + b.first) % b.arrayLength];
        }
        else
        {
            if (aindex < a.size() && bindex >= b.size())
                element[index] = a.element[((aindex++) + a.first) % a.arrayLength];
            else if (aindex >= a.size() && bindex < b.size())
                element[index] = b.element[((bindex++) + b.first) % b.arrayLength];
        }
    }
    return *this;
}

//30. 1 ) 编写方法 circularArrayList<T>::split(lab),它生成两个线性表a 和b。a 包含 *this 中索引为偶
//      数的元素,b 包含其余的元素。
//    2 ) 计算方法的复杂度。
//    3 ) 测试你的代码。
template<class T>
circularArrayList<T> &circularArrayList<T>::split(circularArrayList<T> &a, circularArrayList<T> &b)
{
    if (listSize == 0)
    {
        cout << "listSize == empty";
        return *this;
    }

    a.increaseArray(listSize);
    b.increaseArray(listSize);

    int index, aindex = 0, bindex = 0;
    for (int i = 0; i < listSize; i++)
    {
        if (i % 2 == 0)
        {
            a.element[aindex++] = element[i];
        }
        else
        {
            b.element[bindex++] = element[i];
        }
    }
    a.listSize = (listSize + 1) / 2;
    b.listSize = listSize / 2;

    return *this;
}

//改变容量大小
template <class T>
void circularArrayList<T>::changeArraySize(int capacity)
{
    //新数组
    T *temp = new T[capacity];
	circularCopy(&(element[first]), &(element[last]), element, arrayLength, temp);

    //释放老数组的内存空间
	delete[]element;
	element = temp;

	arrayLength = capacity;
	first = 0;
	last = listSize;
}



int main()
{
    // 创建两个容量为 100 的线性表
    linearList<double> *x = (linearList<double> *)new circularArrayList<int>(100);
    circularArrayList<double> y(100);

    //利用容量的缺省值创建一个线性表
    circularArrayList<char> z;

    //用线性表Y 复制创建一个线性表
    circularArrayList<double> w(y);

    ///
    circularArrayList<double> list;
    cout << "----------------------insert start--------------------" << endl;
    cout << "list capacity = " << list.capacity() << endl;
    cout << "list size = " << list.size() << endl;
    for (int i = 0; i < 50; i++)
    {
        list.insert(0, i);
    }

    cout << "list capacity = " << list.capacity() << endl;
    cout << "list size = " << list.size() << endl;
    cout << list << endl;
    cout << "----------------------insert end--------------------" << endl;
    cout << "----------------------拷贝构造 start--------------------" << endl;
    circularArrayList<double> list5(list);
    cout << "list capacity = " << list.capacity() << endl;
    cout << "list size = " << list.size() << endl;
    cout << list << endl;
    cout << "----------------------拷贝构造 end--------------------" << endl;
    cout << "----------------------indexOf start--------------------" << endl;
    
    for(int i = 0;i<10;i++)
    {
    	list5.insert(50,i+50);
    }
    for(int i = 0;i < 60;i++)
    {
    	std::cout<<list5.indexOf(i)<<" ";
    }
    cout<<endl;
    cout << "----------------------indexOf end--------------------" << endl;
    cout << "----------------------erase start--------------------" << endl;
    cout << "list capacity = " << list.capacity() << endl;
    cout << "list size = " << list.size() << endl;
    cout << list << endl;
    for(int i = 0; i < 20; i++)
    {
    	list.erase(10);
    }
    cout << "list capacity = " << list.capacity() << endl;
    cout << "list size = " << list.size() << endl;
    cout << list << endl;
    cout << "----------------------erase end--------------------" << endl;
#if 0
    cout << "----------------------test trimToSize start--------------------" << endl;
    cout << "list capacity = " << list.capacity() << endl;
    cout << "list size = " << list.size() << endl;
    list.trimToSize();
    cout << "trimToSize " << endl;
    cout << "list capacity = " << list.capacity() << endl;
    cout << "list size = " << list.size() << endl;
    cout << "----------------------test trimToSize end--------------------" << endl;
    ///
    cout << "----------------------setSize trimToSize start--------------------" << endl;
    list.setSize(50);
    cout << "setSize " << endl;
    cout << "list capacity = " << list.capacity() << endl;
    cout << "list size = " << list.size() << endl;
    cout << list << endl;
    cout << "----------------------setSize trimToSize end--------------------" << endl;

    cout << "----------------------operator [] trimToSize start--------------------" << endl;
    cout << "list[10] = " << list[10] << endl;
    list[10] = 100;
    cout << "list[10] = " << list[10] << endl;
    cout << "----------------------operator [] trimToSize end--------------------" << endl;

    cout << "----------------------operator == trimToSize start--------------------" << endl;
    circularArrayList<double> list1;
    for (int i = 0; i < 3; i++)
    {
        list1.insert(0, i);
    }
    cout << (list1 == list) << endl;
    circularArrayList<double> list2;
    list2.insert(0, 2);
    list2.insert(1, 1);
    list2.insert(2, 0);
    cout << (list1 == list2) << endl;
    cout << "----------------------operator == end--------------------" << endl;
    cout << "----------------------operator != start--------------------" << endl;
    cout << (list1 != list) << endl;
    cout << (list1 != list2) << endl;
    cout << "----------------------operator != end--------------------" << endl;
    cout << "----------------------operator < start--------------------" << endl;
    cout << (list1 < list) << endl;
    cout << (list1 < list2) << endl;
    cout << "----------------------operator < end--------------------" << endl;
    cout << "----------------------push_back start--------------------" << endl;
    list1.trimToSize();
    cout << list1 << endl;
    cout << list1.capacity() << endl;
    list1.push_back(111);
    list1.push_back(111);
    list1.push_back(111);
    cout << list1 << endl;
    cout << list1.capacity() << endl;
    cout << "----------------------push_back end--------------------" << endl;
    cout << "----------------------pop_back start--------------------" << endl;
    cout << list1 << endl;
    cout << list1.capacity() << endl;
    cout << list1.pop_back() << endl;
    cout << list1.pop_back() << endl;
    cout << list1.pop_back() << endl;
    cout << list1 << endl;
    cout << list1.capacity() << endl;
    cout << "----------------------pop_back end--------------------" << endl;
    cout << "----------------------swap start--------------------" << endl;
    cout << list << endl;
    cout << list1 << endl;
    cout << "--------------------------" << endl;
    list1.swap(list);
    cout << list << endl;
    cout << list1 << endl;
    cout << "--------------------------" << endl;
    list1.swap(list);
    cout << list << endl;
    cout << list1 << endl;
    cout << "----------------------swap end--------------------" << endl;
    cout << "----------------------reserve start--------------------" << endl;
    std::cout << list1.capacity() << endl;
    list1.reserve(20);
    std::cout << list1.capacity() << endl;
    cout << "----------------------reserve end--------------------" << endl;
    cout << "----------------------set start--------------------" << endl;
    cout << list << endl;
    cout << list.set(3, 100.0);
    cout << list << endl;
    cout << "----------------------set end--------------------" << endl;
    cout << "----------------------clear start--------------------" << endl;
    for (int i = 0; i < 10; i++)
    {
        list2.insert(0, i);
    }
    cout << list2.capacity() << endl;
    cout << list2 << endl;
    list2.clear();
    cout << list2 << endl;
    cout << list2.capacity() << endl;
    cout << "----------------------clear end--------------------" << endl;
    cout << "----------------------removeRange start--------------------" << endl;
    for (int i = 0; i < 10; i++)
    {
        list2.insert(0, i);
    }
    cout << list2 << endl;
    cout << list2.size() << endl;
    list2.removeRange(0, 3);
    cout << list2 << endl;
    cout << list2.size() << endl;
    list2.removeRange(3, 5);
    cout << list2 << endl;
    cout << "----------------------removeRange end--------------------" << endl;
    cout << "----------------------lastIndexOf start--------------------" << endl;
    list2.insert(0, 10);
    list2.insert(1, 10);
    list2.insert(2, 10);
    cout << list2 << endl;
    cout << list2.lastIndexOf(10) << endl;
    cout << list2 << endl;
    cout << "----------------------lastIndexOf end--------------------" << endl;
#endif
    cout << "----------------------reverse start--------------------" << endl;
    cout << list5 << endl;
    list5.reverse();
    cout << list5 << endl;
    cout << "----------------------reverse end--------------------" << endl;
#if 0
    cout << "----------------------leftShift start--------------------" << endl;
    cout << list2 << endl;
    list2.leftShift(4);
    cout << list2 << endl;
    cout << "----------------------leftShift end--------------------" << endl;
    cout << "----------------------circularShift start--------------------" << endl;
    list2.clear();
    for (int i = 0; i < 10; i++)
    {
        list2.insert(0, i);
    }
    cout << list2 << endl;
    list2.circularShift(1);
    cout << list2 << endl;
    list2.circularShift(1);
    cout << list2 << endl;
    list2.circularShift(1);
    cout << list2 << endl;
    list2.circularShift(32);
    cout << list2 << endl;
    cout << "----------------------circularShift end--------------------" << endl;
    cout << "----------------------half start--------------------" << endl;
    cout << list2 << endl;
    list2.half();
    cout << list2 << endl;
    cout << "----------------------half end--------------------" << endl;
    cout << "----------------------iterator start--------------------" << endl;
    cout << list2 << endl;
    cout << (*list2.begin()) << endl;
    circularArrayList<double>::iterator iter;
    cout << "size = " << list2.size() << endl;
    for (iter = list2.begin(); iter != list2.end(); iter++)
    {
        cout << *iter << " ";
    }
    cout << endl;
    for (auto value : list2)
    {
        cout << value << " ";
    }
    cout << endl;

//  std::sort<circularArrayList<double>::iterator>(list2.begin(),list2.end(),std::less);

    cout << (*list2.end()) << endl;
    cout << list2 << endl;
    cout << "----------------------iterator end--------------------" << endl;
#endif
    cout << "----------------------meld start--------------------" << endl;
    circularArrayList<double> list4;
    cout << list << "\ncapacity= " << list.capacity() << " size = " << list.size() << endl;
    cout << list5 << "\ncapacity= " << list5.capacity() << " size = " << list5.size() << endl;
    cout << list4 << "\ncapacity= " << list4.capacity() << " size = " << list4.size() << endl;
    list4.meld(list, list5);
    cout << endl;
    cout << list << "\ncapacity= " << list.capacity() << " size = " << list.size() << endl;
    cout << list5 << "\ncapacity= " << list5.capacity() << " size = " << list5.size() << endl;
    cout << list4 << "\ncapacity= " << list4.capacity() << " size = " << list4.size() << endl;
    cout << "----------------------meld end--------------------" << endl;

    cout << "----------------------merge start--------------------" << endl;
    circularArrayList<double> list1;
    circularArrayList<double> list2;
    circularArrayList<double> list3;
  
    list1.clear();
    list2.clear();
    list3.clear();
    for (int i = 0; i < 10; i++)
    {
        list1.push_back(2 * i);
    }
    for (int i = 0; i < 20; i++)
    {
        list2.push_back(2 * i + 1);
    }
    cout << list1 << "capacity= " << list1.capacity() << " size = " << list1.size() << endl;
    cout << list2 << "capacity= " << list2.capacity() << " size = " << list2.size() << endl;
    cout << list3 << "capacity= " << list3.capacity() << " size = " << list4.size() << endl;

    list3.merge(list1, list2);

    cout << list1 << "capacity= " << list1.capacity() << " size = " << list1.size() << endl;
    cout << list2 << "capacity= " << list2.capacity() << " size = " << list2.size() << endl;
    cout << list3 << "capacity= " << list3.capacity() << " size = " << list4.size() << endl;
    cout << "----------------------merge end--------------------" << endl;
#if 0

    cout << "----------------------split start--------------------" << endl;
    cout << list1 << "capacity= " << list1.capacity() << " size = " << list1.size() << endl;
    cout << list2 << "capacity= " << list2.capacity() << " size = " << list2.size() << endl;
    cout << list3 << "capacity= " << list3.capacity() << " size = " << list4.size() << endl;
    list3.split(list1, list2);
    cout << list1 << "capacity= " << list1.capacity() << " size = " << list1.size() << endl;
    cout << list2 << "capacity= " << list2.capacity() << " size = " << list2.size() << endl;
    cout << list3 << "capacity= " << list3.capacity() << " size = " << list4.size() << endl;
    cout << "----------------------split end--------------------" << endl;
#endif
    return 0;
}

测试输出

xz@xiaqiu:~/study/algorithm/c++/1/build$ ./test 
----------------------insert start--------------------
list capacity = 10
list size = 0
list capacity = 80
list size = 50
49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 
----------------------insert end--------------------
----------------------拷贝构造 start--------------------
list capacity = 80
list size = 50
49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 
----------------------拷贝构造 end--------------------
----------------------indexOf start--------------------
49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 59 58 57 56 55 54 53 52 51 50 
----------------------indexOf end--------------------
----------------------erase start--------------------
list capacity = 80
list size = 50
49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 
list capacity = 80
list size = 30
49 48 47 46 45 44 43 42 41 40 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 
----------------------erase end--------------------
----------------------reverse start--------------------
49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 59 58 57 56 55 54 53 52 51 50 
50 51 52 53 54 55 56 57 58 59 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 
----------------------reverse end--------------------
----------------------meld start--------------------
49 48 47 46 45 44 43 42 41 40 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 
capacity= 80 size = 30
50 51 52 53 54 55 56 57 58 59 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 
capacity= 80 size = 60

capacity= 10 size = 0

49 48 47 46 45 44 43 42 41 40 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 
capacity= 80 size = 30
50 51 52 53 54 55 56 57 58 59 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 
capacity= 80 size = 60
49 50 48 51 47 52 46 53 45 54 44 55 43 56 42 57 41 58 40 59 19 0 18 1 17 2 16 3 15 4 14 5 13 6 12 7 11 8 10 9 9 10 8 11 7 12 6 13 5 14 4 15 3 16 2 17 1 18 0 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 
capacity= 160 size = 90
----------------------meld end--------------------
----------------------merge start--------------------
capacity > arrayLength || capacity < 0
capacity > arrayLength || capacity < 0
capacity > arrayLength || capacity < 0
0 2 4 6 8 capacity= 10 size = 5
1 3 5 7 9 capacity= 10 size = 5
capacity= 10 size = 90
input capacity <= arrayLength10
0 2 4 6 8 capacity= 10 size = 5
1 3 5 7 9 capacity= 10 size = 5
9 0 0 0 0 0 0 0 0 0 capacity= 10 size = 90
----------------------merge end--------------------
xz@xiaqiu:~/study/algorithm/c++/1/build$ 

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-12-05 12:17:23  更:2021-12-05 12:18:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 14:46:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码