第一次写博客,很是兴奋!
由于最近网上看到很多面试管对STL算法较感兴趣,于是就想自己写个vector容器,实现STL内部自带的基本功能。借鉴于博主yysdsyl写的vector,很是感谢!
下面是整个vector包装。
//////////////////////////////////////////////////////////////////////////////////////
为了实现vetor的排序功能,我选择了快排
#ifndef COMMON_ZHAOYAN_HHH
#define COMMON_ZHAOYAN_HHH
#include "resource.h"
///////////////////////////////////////////////////////////////////////////////////
/* 1 sort 2 reverse */
///////////////////////////////////////////////////////////////////////////////////
template <typename T> extern void QuickSort(T a[] , size_t m , size_t n , size_t mode)
{
if(m < n){
T temp = a[m];
size_t i = m , j = n;
while(m < n){
if(mode == 2) while(temp >= a[n] && m < n) -- n;
else while(temp <= a[n] && m < n) -- n;
if(m < n) swap(a[n] , a[m]);
if(mode == 2) while(temp <= a[m] && m < n) ++ m;
else while(temp >= a[m] && m < n) ++ m;
if(m < n) swap(a[m] , a[n]);
}
QuickSort(a , m + 1 , j , mode);
if(m == 0) m = 1;
QuickSort(a , i , m - 1 , mode);
}else return;
}
#endif
////////////////////////////////////////////////////////////////////////////////
为了防止出现异常,我添加了很小的异常判断
#ifndef RESOURCE_ZY_HHH
#define RESOURCE_ZY_HHH
#include "iostream"
#include<cstddef>
#include<cassert>
#include "string"
#include "exception"
using namespace std;
class MyException : public exception
{
public:
MyException(const string whatString):exception(whatString)
{
cout << whatString << endl;
}
};
#endif
//////////////////////////////////////////////////////////////////////////////////
下面是vector的基本功能,包括元素数目,排序,插入,删除,添加,倒序等功能
#ifndef MYVECTOR_ZY_HHHH
#define MYVECTOR_ZY_HHHH
#include "resource.h"
#include "common.h"
//////////////////////////////////////////////////////////////////
/* 实现vector容器基本功能 */
//////////////////////////////////////////////////////////////////
template <typename T> class MyVector{
public:
MyVector(size_t size , size_t init = 0);
MyVector();
~MyVector();
void push_back(T);
size_t GetSize();
void ReSize(size_t size , size_t init = -1);
T& operator[](size_t i);
T* begin();
void clear();
void erease(size_t i);
void insert(size_t num , size_t i);
void sort();
void reverse();
void SWAP(size_t a , size_t b);
private:
T* data;
size_t RSize;//数组中元素具体数目
size_t PSize;//数组开辟的大小
} ;
template <typename T> MyVector<T>::MyVector():PSize(1024)
{
this->data = (T* )malloc(sizeof(T) * PSize);
this->RSize = 0;
}
template <typename T> void MyVector<T>::SWAP(size_t a , size_t b)
{
assert(this->RSize >= 2);
T temp = this->data[a];
this->data[a] = this->data[b];
this->data[b] = temp;
}
template <typename T> void MyVector<T>::erease(size_t i)
{
if(i < 0 || i > this->RSize)throw MyException("out of vector border!");
else{
T* p = (T* )malloc(sizeof(T) * this->PSize);
copy(this->data , this->data + i , p);
copy(this->data + i + 1 , this->data + this->RSize , p + i);
free(this->data);
-- this->RSize;
this->data = p;
}
}
template <typename T> void MyVector<T>::insert(size_t num , size_t i)
{
if(i < 0 || i > this->RSize) throw MyException("out of vector border!");
else{
if(this->RSize == this->PSize) this->PSize *= 2;
T* p = (T* )malloc(sizeof(T) * this->PSize);
copy(this->data , this->data + i , p);
p[i] = num;
copy(this->data + i , this->data + this->RSize , p + i + 1);
free(this->data);
++ this->RSize;
this->data = p;
}
}
template <typename T> void MyVector<T>::clear()
{
this->RSize = 0;
free(this->data);
}
template <typename T> MyVector<T>::MyVector(size_t size , size_t init = 0):PSize(1024)
{
assert(size >= 0);
if(size == 0){
this->data = NULL;
this->RSize = 0;
}else{
while(this->PSize <= size)
this->PSize *= 2;
this->data = (T* )malloc(sizeof(T) * this->PSize);
memset(data , init , sizeof(T) * size);
new(this->data) T[size];
this->RSize = size;
}
}
template <typename T> MyVector<T>::~MyVector()
{
/* free(this->data);
this->data=NULL;
this->RSize = 0;
this->PSize = 0;*/
}
template <typename T> void MyVector<T>::push_back(T num)
{
if(this->RSize == this->PSize){
this->PSize *= 2;
T* p = (T* )malloc(sizeof(T) * (this->PSize));
memcpy(p , this->data , sizeof(T) * RSize);
free(this->data);
this->data = p;
}
memcpy(&(this->data[this->RSize]),&num,sizeof(num));
++ this->RSize;
}
template <typename T> void MyVector<T>::ReSize(size_t size , size_t init = -1)
{
if(init != -1) memset(this->data , init , sizeof(T) * size);
if(this->RSize > size) this->RSize = size;
new(this->data)T[size];
}
template <typename T> size_t MyVector<T>::GetSize()
{
return this->RSize;
}
template <typename T> T* MyVector<T>::begin()
{
return this->data;
}
template <typename T> T& MyVector<T>::operator[](size_t i)
{
if(i < 0 || i >this->RSize - 1){
throw MyException("out of vector border!");
exit(0);
}else return this->data[i];
}
template <typename T> void MyVector<T>::sort()
{
if(this->RSize == 0) throw MyException("no element in MyVector!");
else{
QuickSort(this->data , 0 , this->RSize - 1 , 1);
}
}
template <typename T> void MyVector<T>::reverse()
{
if(this->RSize == 0) throw MyException("no element in MyVector!");
else{
QuickSort(this->data , 0 , this->RSize - 1 , 2);
}
}
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////////////
下面是测试函数
#include "MyVector.h"
int main()
{
MyVector<int> vec;
MyVector<MyVector<int>> v;
for(int i = 0; i < 12; ++ i)
{
vec.push_back(i);
cout<<vec[i]<<endl;
}
v.push_back(vec);
v[0].push_back(2);
int i = 0;
try{
//vec.sort();
for(i = 0; i < v.GetSize(); ++ i){
for(int j = 0; j < v[i].GetSize(); ++ j)
printf("%d " ,v[i][j]);
}
}catch(MyException e){
cout << i << endl;
}
return 0;
}
结果如下:
整个过程中难点在于指针地址的复制与赋值,浅复制和深复制,还有析构函数的工作原理。不过对于析构函数还是有点疑惑,当对象传进去时,在局部变量自动释放的时候如何不调用析构函数呢?希望大神能给予指点迷津。