邓俊辉老师《数据结构》(一)-给Vector添加移动拷贝赋值运算

在学习邓俊辉老师的《数据结构》一书时,发现Vector数据结构内没有移动构造,移动赋值等构造函数,遂想着添加上拷贝赋值运算。

Vector部分代码

/*
 * @Author: your name
 * @Date: 2020-09-06 09:07:54
 * @LastEditTime: 2020-09-06 09:24:20
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \code20200906\Vector.h
 */
#ifndef VECTOR_H
#define VECTOR_H
typedef int Rank;             //using Rank=int;
#define DEFAULT_CAPACITY  3 //默认的初始容量(实际应用中可设置为更大)
#include <memory>

template <typename T>
class Vector
{ //向量模板类
protected:
    Rank _size;                                  //规模
    int _capacity;                               //容量
    T* _elem;                                    //数据区
    void copyFrom(T const* A, Rank lo, Rank hi); //复制数组区间;作为一个辅助函数来使用,
                                                 //构造函数多次用到
    void expand();                               //空间不足时扩容
    void shrink();                               //装填因子过小时压缩
    bool bubble(Rank lo, Rank hi);               //扫描交换
    void bubblesort(Rank lo, Rank hi);           //气泡排序法;
    Rank max(Rank lo, Rank hi);                  //选取最大元素
    void selectionSort(Rank lo, Rank hi);        //选择排序法
    void merge(Rank lo, Rank hi);                //归并算法
    void mergesort(Rank lo, Rank hi);            //归并排序
    Rank partition(Rank lo, Rank hi);            //轴点构造算法
    void quiksort(Rank lo, Rank hi);             //快速排序算法;
    void heapsort(Rank lo, Rank hi);             //堆排序
public:
    //构造函数
    //默认构造函数
    //此默认构造函数我觉着不好,用下面的吧
    //Vector(int c = DEFAULT_CAPACITY,int s , 0,T v = 0) //容量为c,规模为s,所有元素初始为v
    //{
    //  //构建容量大小
    //  _elem = new T[_capacity = c];
    //  for (_size = 0; _size < s; _elem[_size++] = v);
    //}//:_elem(new T[_capacity=c]),_capacity(c),_size(s)
    Vector(int c = DEFAULT_CAPACITY,int s= 0, T v = 0) :_elem(new T[c]), _capacity(c), _size(s) //容量为c,规模为s,所有元素初始为v
    {
        //构建容量大小
        
        for (int i = 0; i < _size; ++i)
            _elem[i] = v;
    }
    Vector(T const* A, Rank n) { copyFrom(A, 0, n); }//数组整体复制//T const ;const T 都一样,指的是指向常对象的指针
    Vector(T const* A, Rank lo, Rank hi) { copyFrom(A, lo, hi); }//区间整体复制
    //拷贝构造函数
    Vector(Vector<T> const& V) { copyFrom(V._elem, 0, V._size); }//向量整体复制

    /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    Vector(Vector<T>&& V);//移动构造函数

     /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    Vector& operator=(const Vector<T>&);//拷贝赋值
    Vector& operator=(Vector<T>&&);//移动构造赋值
    Vector(Vector<T> const& V, Rank lo, Rank hi) { copyFrom(V._elem, lo, hi); }//区间复制
    //析构函数
    ~Vector() { delete[]_elem; }//释放内部空间,需要析构函数的也需要构造函数和拷贝赋值函数

    //只读访问接口
    Rank size()const { return _size; }//规模
    bool empty()const  { return !_size; }//自己写成了_size==0
    int disordered()const;//判断向量是否已排序
    Rank find(T const& e)const { return find(e, 0, _size); }//无序向量整体查找,调用下面的函数
    Rank find(T const& e, Rank lo, Rank hi)const;//无序向量区间查找
    Rank search(T const& e)const//有序向量整体查找
    {return (0 >= _size ? -1: search(e, 0, _size)); }
    Rank search(T const& e, Rank lo, Rank hi)const;//有序向量区间查找
    //可写访问接口
    T& operator[](Rank r)const;//重载下标运算符
    T remove(Rank r);//删除秩为r的元素
    int remove(Rank lo, Rank hi);//删除区间内的元素
    Rank insert(Rank r, T const& e);//插入元素
    Rank insert(T const& e) { return insert(_size, e); }//默认作为末尾元素插入
    void sort(Rank lo, Rank hi);//对区间内排序
    void sort() { sort(0, _size); }//整体排序
    void unsort(Rank lo, Rank hi);//对区间置乱
    void unsort() { unsort(0, _size); }//整体置乱
    int deduplicate();//无序去重
    int uniquify();//有序去重

    //遍历
    void traverse(void(*)(T&));//遍历
    template<typename VST>void traverse(VST&);//遍历
};

//具体到功能的实现
template<typename T>
void Vector<T> ::copyFrom(T const* A, Rank lo, Rank hi) {//运行时间正比于O(_size)
    //以数组区间A[lo,hi)为蓝本复制对象
    _elem = new T[_capacity = 2 * (hi - lo)]; _size = 0;//分配空间,规模清零,2倍的空间
    while (lo < hi) {
        _elem[_size++] = A[lo++];//复制到_elem[0,hi-lo)
    }
}

template<typename T>
Vector<T>& Vector<T>::operator =(const Vector<T>& V) {
    //拷贝赋值的功能类似于析构+构造
    if (_elem)delete[]_elem;
    copyFrom(V._elem,0,V.size());
    return *this;
}
template<typename T>
Vector<T>& Vector<T>::operator=(Vector<T>&& V) {

    if (this != &V)//注意取V的地址
    {
        delete[]_elem;
        _elem = V._elem;
        _size = V._size;
        _capacity = V._capacity;
        V._elem = nullptr;
    }
    return *this;
}








#endif

测试主函数代码

/*
 * @Author: your name
 * @Date: 2020-09-06 09:07:12
 * @LastEditTime: 2020-09-06 09:07:45
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \code20200906\main.cpp
 */
#include"Vector.h"
#include <ctime>
#include <iostream>
int main(int argc, char** argv) {

    Vector<int> v(1000000000, 1000000000, 5);
    Vector<int> v1;
    Vector<int> v2;
    std::clock_t t_start, t_end;
    t_start = std::clock();
    v1 = v;
    t_end = std::clock();
    std::cout << "拷贝赋值运算耗时: " << double(t_end - t_start) / 1000.0 << " S" << "\n";
    

    t_start = std::clock();
    v2 = std::move(v);
    t_end = std::clock();
    std::cout << "移动赋值运算耗时: " << double(t_end - t_start) / 1000.0 << " S" << "\n";



    return 0;
}

对比结果

运行时间结果

结论

  1. 移动赋值运算由于没有申请新空间,赋值等操作比拷贝赋值运算快许多;
  2. 但是只有在源对象不再使用等情况下才可以使用移动赋值。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343