Vector动态实现
思想:
- vector在定义时预留了一部分内存空间来用于存储新增的元素。
- 当添加元素时,如果vector空间大小不足,则会以原大小的两倍另外配置一块较大的新空间,然后将原空间内容拷贝过来,在新空间的内容末尾添加元素,并释放原空间。
- vector的空间动态增加大小,并不是在原空间之后的相邻地址增加新空间,因为vector的空间是线性连续分配的,不能保证原空间之后有可供配置的空间。因此,对vector的任何操作,一旦引起空间的重新配置,指向原vector的所有迭代器就会失效。
部分可借鉴的代码:
建立动态数组时使用模板类:
template<typename T>
class Vector{
public:
//构造函数,复制构造函数以及析构函数
Vector(int size=0):theSize(size),theCapacity(0+5)
{
objects=new T[theCapacity];
}
Vector(const Vector& rhs):objects(NULL)
{
operator=(rhs);
}
~Vector()
{
delete[] objects;
}
// 重载=号操作符
const Vector& operator=(const Vector& rhs)
{
theCapacity=rhs.theCapacity;
theSize=rhs.theSize;
objects=new objects[this->theCapacity];
for(int i=0;i<this->theSize;i++)
objects[i]=rhs.objects[i];
return *this;
}
//内存空间不足时,以原大小的两倍另外配置一块较大的新空间。
//然后将原空间内容拷贝过来,在新空间的内容末尾添加元素,并释放原空间。
void resize(int newSize)
{
if(newSize>theCapacity)
reserve(newSize*2+1);
theSize=newSize;
}
//调整预留的空间,也就是实际上申请的内存的大小
void reserve(int newCapacity)
{
if(newCapacity<theSize)
return;
T* oldObject=objects;
objects=new T[newCapacity];
theCapacity=newCapacity;
for(int i=0;i<theSize;i++)
objects[i]=oldObject[i];
delete objects;
}
//重载[]操作符
T& operator[](int index)
{
return *(objects+index);
}
//成员常数函数
const T& operator[](int index)const
{
return *(objects+index);
}
//几个get函数,均为const成员,保证const对象也能调用
bool isEmpty() const
{
return getSize()==0;
}
int capacity() const
{
return theCapacity;
}
int size() const
{
return theSize;
}
//push和pop操作
void push_back(T t)
{
if(theSize==theCapacity)
reserve(theCapacity*2+1);
objects[theSize++]=t;
}
void pop_back()
{
theSize--;
}
T& back()
{
return objects[theSize-1];
}
const T& back()const
{
return objects[theSize-1];
}
// 迭代器
typedef T* iterater;
typedef const T* const_iterater;
//begin end 等操作
iterater begin()
{
return objects;
}
const_iterater begin() const
{
return objects;
}
iterater end()
{
return (objects+theSize);
}
const_iterater end() const
{
return (objects+theSize);
}
private:
T* objects;
int theSize;
int theCapacity;
}
哈希表
在有网络的情况下,可以看以下几篇文章,相对浅显易懂讲述了关于哈希表的知识:
1. 浅谈算法和数据结构(11):哈希表
2. 为什么哈希表能够加快查找效率?
3. 哈希函数以及冲突解决常见方法
4. 举例子说明
下面是简单理解,具体还是需要看上述整理的工具书:
哈希表就是一种键-值(key-indexed)对应存储数据的结构(类似map,我们只要输入待查找的值即key,即可查找到其对应的值。
哈希的思路:
如果所有的键都是整数,那么就可以使用一个简单的无序数组来实现:将键作为索引,值即为其对应的值,这样就可以快速访问任意键的值。这是对于简单的键的情况,我们将其扩展到可以处理更加复杂的类型的键。
哈希查找步骤:
1. 使用哈希函数将被查找的键转换为数组的索引。理想的情况下,不同的键会被转换为不同的索引值,但是有些情况下我们需要处理多个键被哈希到同一个索引值的情况。
2. 处理哈希碰撞冲突。
哈希函数:
哈希函数的构造方法很多,最好的情况是:关键字经过哈希函数得到一个随机的地址,以便使一组关键字的哈希地址均匀分布在整个地址空间中,从而减少冲突。通常若所给关键字不是自然数,将其转换为自然数。
冲突解决:
当产生冲突时,进行二次计算。如:直接定址法建立一个数组,当哈希函数计算不同键对应于同一地址时,线性顺延查找到空位为止。
查找效率:
由于查找关键字对应值的时候,是可以通过预先设计的哈希函数计算找到对应地址的,因此查找的效率可以达到O(1)
。即使存在哈希碰撞,由于也是可以通过计算或者预先定义的线性表长度二次计算找到,相较于直接查找效率已经是大幅提高了。