• C++实现动态顺序表


       顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。这样的存储方式使得线性表逻辑上相邻的元素,其在物理存储单元中也是相邻的。只要知道了第一个元素的存储地址,就可以知道线性表中任何一个元素的存储地址。本文利用C++语言,在Windows平台 Visual Studio 2015开发环境下实现。功能:应用C++语言实现顺序表的各项操作。基本的成员函数:构造函数、拷贝构造函数、赋值运算符的重载、析构函数。

    // 顺序表构造成功之后,里面存放了n个元素data
    Vector(size_t n, const DataType& data = DataType());
    Vector(const Vector& v);  
    Vector& operator=(const Vector& v);
    ~Vector();   

    void PushBack(const DataType& data);  //尾插
    void PopBack();  //尾删 

    void Print()//打印顺序表

    // 给顺序表重新赋值,该函数执行完里面存放了n个元素data
    void Assign(size_t n, const DataType& data);

    // 在顺序表的pos位置上插入元素data
    void Insert(size_t pos, const DataType& data);

    // 删除顺序表pos位置上的元素
    void Erase(size_t pos);

    // 改变顺序表中的元素为n个,如果n>原来顺序表中的元素的个数,多出来的空间用data来填充
    void ReSize(size_t n, const DataType& data = DataType());

    // 清空顺序表中的元素-->请自己动手验证是否需要清理vector中的空间
    void Clear();

    // 返回顺序表中有效元素的大小
    size_t Size()const;

    // 返回顺序表中空间容量的大小
    size_t Capacity()const;

    // 顺序表是否为空,若为空返回true,否则返回null
    bool Empty()const;

    // 通过下边访问顺序表index位置上的元素。 思考为什么要成对的来重载
    DataType& operator[](size_t index);
    const DataType& operator[](size_t index)const;

    // 返回顺序表中第一个元素的引用,思考为什么要返回应用,为什么要成对重载
    DataType& Front();
    const DataType& Front()const;

    // 返回顺序表中最后一个的元素的引用,思考为什么要返回引用,为什么要成对重载
    DataType& Back();
    const DataType& Back()const;

    void _CheckCapacity()// 动态扩容

    int Find(const DataType & data)//查找数据

      1 #ifndef __VECTOR_H__
      2 #define __VECTOR_H__
      3 
      4 #include<iostream>
      5 #include<stdio.h>
      6 #include<assert.h>
      7 using namespace std;
      8 
      9 #define COW 4
     10 typedef int DataType;
     11 
     12 class Vector
     13 {
     14 public:
     15     Vector()
     16         : _array(NULL)
     17         , _size(0)
     18         , _capacity(0)
     19     {}
     20 
     21     // 顺序表构造成功之后,里面存放了n个元素data
     22     Vector(size_t n, const DataType& data = DataType())
     23     {
     24             _array = new DataType[n];
     25             _size = n;
     26             _capacity = n;
     27             for(size_t i = 0; i<n;i++)
     28             _array[i] = data;
     29             
     30     }
     31     Vector(const Vector& v)
     32         :_array(new DataType[v._size])
     33         , _size(v._size)
     34         ,_capacity(v._capacity)
     35     {
     36         memcpy(_array, v._array, sizeof(DataType)*_size);
     37     }
     38     Vector& operator=(const Vector& v)
     39     {
     40         if (this != &v)
     41         {
     42             DataType *temp = new DataType[v._size];
     43             temp = v._array;
     44             delete[] _array;
     45             _array = temp;
     46             _size = v._size;
     47             _capacity = v._capacity;
     48             memcpy(_array, v._array, sizeof(DataType)*_size);
     49         }
     50         return *this;
     51     }
     52     ~Vector()
     53     {
     54         if (_array)
     55         {
     56             delete[] _array;
     57             _array = NULL;
     58             _size = 0;
     59             _capacity = 0;
     60         }
     61     }
     62 
     63 public:
     64     void PushBack(const DataType& data)
     65     {
     66         _CheckCapacity();
     67         _array[_size++] = data;
     68     }
     69     void PopBack()
     70     {
     71         assert(!Empty());
     72         --_size;
     73     }
     74     void Print()
     75     {
     76         for (size_t i = 0; i < _size; ++i)
     77         {
     78             cout << _array[i] << " ";
     79         }
     80         cout << endl;
     81     }
     82     // 给顺序表重新赋值,该函数执行完里面存放了n个元素data
     83     void Assign(size_t n, const DataType& data)
     84     {
     85         assert(n<_size);    
     86         for (size_t i = 0; i<n; i++)
     87             _array[i] = data;
     88     }
     89 
     90     // 在顺序表的pos位置上插入元素data
     91     void Insert(size_t pos, const DataType& data)
     92     {
     93         assert(pos<_size);    //需检验pos的合法性
     94         _CheckCapacity();
     95         if (pos == _size - 1)  //在最后一个位置插入数据等于尾插
     96         {
     97             PushBack(data);
     98             return;
     99         }
    100         else
    101         {
    102             for (size_t i = _size; i > pos; --i)
    103             {
    104                 _array[i] = _array[i - 1];
    105             }
    106             _array[pos] = data;
    107             _size++;
    108         }
    109     }
    110 
    111     // 删除顺序表pos位置上的元素
    112     void Erase(size_t pos)
    113     {
    114         assert(pos<_size);    //需检验pos的合法性
    115         if (pos == _size - 1)  //在最后一个位置删除数据等于尾删
    116         {
    117             PopBack();
    118             return;
    119         }
    120         else
    121         {
    122             for (size_t i = pos; i < _size - 1; i++)
    123             {
    124                 _array[i] = _array[i + 1];
    125             }
    126             --_size;
    127         }        
    128     }
    129 
    130     // 改变顺序表中的元素为n个,如果n>原来顺序表中的元素的个数,多出来的空间
    131     // 请用data来填充
    132     void ReSize(size_t n, const DataType& data = DataType())
    133     {
    134         if (n > _size)
    135         {
    136             size_t i = _size;
    137             _size = n;
    138             _CheckCapacity();
    139             for (i; i < n; i++)
    140                 _array[i] = data;
    141         }
    142         else
    143         {
    144             size_t i = n;
    145             for(i; i<_size; i++)
    146                 PopBack();
    147         }
    148     }
    149 
    150     // 清空顺序表中的元素-->请自己动手验证是否需要清理vector中的空间
    151     void Clear()
    152     {
    153         delete[] _array;
    154         _array = NULL;
    155         _size = 0;
    156         _capacity = 0;
    157     }
    158     // 返回顺序表中有效元素的大小
    159     size_t Size()const
    160     {
    161         return _size;
    162     }
    163     // 返回顺序表中空间容量的大小
    164     size_t Capacity()const
    165     {
    166         return _capacity;
    167     }
    168     // 顺序表是否为空,若为空返回true,否则返回null
    169     bool Empty()const
    170     {
    171         return _size == 0;
    172     }
    173 
    174     // 通过下边访问顺序表index位置上的元素
    175     // 思考为什么要成对的来重载
    176     DataType& operator[](size_t index)
    177     {
    178         assert(index);
    179         return _array[index];
    180     }
    181     const DataType& operator[](size_t index)const
    182     {
    183         assert(index);
    184         return _array[index];
    185     }
    186     // 返回顺序表中第一个元素的引用,思考为什么要返回应用,为什么要成对重载
    187     DataType& Front()
    188     {
    189         return _array[0];
    190     }
    191     const DataType& Front()const
    192     {
    193         return _array[0];
    194 
    195     }
    196     // 返回顺序表中最后一个的元素的引用,思考为什么要返回引用,为什么要成对重载
    197     DataType& Back()
    198     {
    199         return _array[_size - 1];
    200     }
    201     const DataType& Back()const
    202     {
    203         return _array[_size - 1];
    204     }
    205 private:
    206     // 动态扩容-->该函数中有坑,请找出坑在哪?
    207     void _CheckCapacity()
    208     {
    209         // 2*_capacity  有问题?
    210         if (_size >= _capacity)
    211         {
    212             DataType* pTemp = new DataType[_capacity * 2];
    213             //memcpy(pTemp, _array, _size*sizeof(DataType));
    214             for (size_t index = 0; index < _size; ++index)
    215                 pTemp[index] = _array[index];
    216             delete[] _array;
    217             _array = pTemp;
    218             _capacity *= 2;
    219         }
    220     }
    221     int Find(const DataType & data)
    222     {
    223         assert(_array != NULL);
    224         for (size_t i = 0; i < _size; i++)
    225         {
    226             if (_array[i] == data)
    227                 return i;
    228         }
    229         return -1;
    230     }
    231 private:
    232     DataType* _array;
    233     size_t _size;  // 保存有效元素的个数
    234     size_t _capacity;  // 空间的实际大小
    235 };
    236 
    237 #endif //__VECTOR_H__

    代码当中的问题及思考提示将在下一篇文章中探讨。

  • 相关阅读:
    SpringCloud(七)之SpringCloud的链路追踪组件Sleuth实战,以及 zipkin 的部署和使用
    java动态代理实现与原理详细分析
    Java中List, Integer[], int[]的相互转换
    Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore
    lock wait timeout exceeded; try restarting transactio解决方案
    java命令--jstack 工具 查看JVM堆栈信息
    kafka入门:简介、使用场景、设计原理、主要配置及集群搭建(转)
    Spring全局异常处理
    SpringBoot学习:整合shiro自动登录功能(rememberMe记住我功能)
    mysql函数之截取字符串
  • 原文地址:https://www.cnblogs.com/33debug/p/6664281.html
Copyright © 2020-2023  润新知