顺序表
一段地址连续的内存
- 普通数组
int arr[5] = {1,2,3,4,5};
- 申请堆内存
int* pArr = new int[5];
在堆内申请一块能容纳5个int类型的地址。
- 动态数组
有时候由于新数据的加入,而原有内存不够,需要增加内存。
//pArr为存数据的内存, size 为 当前内存大小, newData为要插入的数据
void add_Data(int*& pArr, int size, int newData)
{
//开空间
int* pNew = new int[size + 1];
if (pArr)
{
//原有数据拷贝过来
memcpy(pNew, pArr, sizeof(int) * size);
//释放原有内存段
delete[] pArr;
}
//pArr指向新内存段
pArr = pNew;
//新数据进来
pArr[size++] = newData;
}
该函数实现了往一块内存中插入一个int数据的功能。
分析:
每次插入时都要重新申请一次内存空间,这就会影响性能。
- 优化后的动态数组
考虑到不能每次有新数据进来就重新申请内存,我们可以一开始就申请一块较大的内存,不过这种方式虽然提升了效率,但浪费空间。
所以要做到时间空间的平衡(不能一次申请太多空间),经过推算发现,每次取原内存的1.5倍是最合适的。
int capacity = 0; //保存现在空间大小
void add_Data(int*& pArr, int size, int newData)
{
//计算新开空间大小
if (size >= capacity)
{
capacity = capacity + ((capacity >> 1) > 1 ? (capacity >> 1) : 1);//用>>比乘1/2效率高
}
//开空间
int* pNew = new int[capacity];
if (pArr)
{
//原有数据拷贝过来
memcpy(pNew, pArr, sizeof(int) * size);
//释放原有内存段
delete[] pArr;
}
//pArr指向新内存段
pArr = pNew;
//新数据进来
pArr[size++] = newData;
}