vector的实现 vector.h
#pragma once
#include <cassert>
#include <iostream>
#include <cstdlib>
#include <ctime>
namespace MYSTL
{
typedef int Rank;
const int DEFAULT_CAPACITY = 5;
template<typename T>
class vector
{
public:
friend std::ostream& operator<< (std::ostream& os, const vector<T> &v)
{
for (Rank i = 0; i < v.m_size; ++i)
os << v.m_data[i] << " ";
return os;
}
public:
vector(int cap = DEFAULT_CAPACITY, int sz = 0, const T v = T());
vector(const T *arr, int n) { copyFrom(arr, 0, n); }
vector(const T *arr, Rank lo, Rank hi) { copyFrom(arr, lo, hi); }
vector(const vector<T> &v) { copyFrom(v.m_data, 0, v.m_size); }
vector(const vector<T> &v, Rank lo, Rank hi) { copyFrom(v.m_data, lo, hi); }
~vector() { delete [] m_data; }
vector<T>& operator = (const vector<T> &v);
int capacity() const { return m_capacity; }
int size() const { return m_size; }
bool empty() const { return !m_size; }
Rank find(const T &e) const;
Rank find(const T &e, Rank lo, Rank hi) const;
Rank search(const T &e) const;
Rank search(const T &e, Rank lo, Rank hi) const;
int disordered() const;
void push_back(const T &e) { insert(e); }
void pop_back() { remove(m_size - 1); }
T& operator[](Rank r) { assert(r >= 0 && r < m_size); return m_data[r]; }
Rank insert(Rank r, const T &e);
Rank insert(const T &e);
const T remove(Rank r);
int remove(Rank lo, Rank hi);
void clear();
int deduplicate();
int uniquify();
void sort(Rank lo, Rank hi);
void sort();
protected:
void copyFrom(const T *data, Rank lo, Rank hi);
void expand();
void shrink();
void bubbleSort(Rank lo, Rank hi);
void selectSort(Rank lo, Rank hi);
void insertSort(Rank lo, Rank hi);
void mergeSort(Rank lo, Rank hi);
void merge(Rank lo, Rank mid, Rank hi);
Rank binSearch(const T &e, Rank lo, Rank hi) const;
Rank binSearch_impl1(const T &e, Rank lo, Rank hi) const;
Rank binSearch_impl2(const T &e, Rank lo, Rank hi) const;
Rank binSearch_impl3(const T &e, Rank lo, Rank hi) const;
private:
int uniquify_impl1();
int uniquify_impl2();
static void swap(T &a, T &b) { T tmp = a; a = b; b = tmp; }
protected:
Rank m_capacity;
Rank m_size;
T *m_data;
};
template<typename T>
vector<T>::vector(int cap = DEFAULT_CAPACITY, int sz = 0, T v = T())
: m_capacity(cap), m_size(sz)
{
m_data = new T[m_capacity];
for (int i = 0; i < m_size; ++i)
m_data[i] = v;
}
template<typename T>
inline vector<T>& vector<T>::operator=(const vector<T>& v)
{
if (m_data == v.m_data)
return *this;
delete[] m_data;
copyFrom(v.m_data, 0, v.m_size);
return *this;
}
template<typename T>
inline Rank vector<T>::find(const T & e) const
{
return find(e, 0, m_size);
}
template<typename T>
inline Rank vector<T>::find(const T & e, Rank lo, Rank hi) const
{
assert(lo >= 0 && hi <= m_size && lo < hi);
while (--hi >= lo)
{
if (e == m_data[hi])
return hi;
}
return -1;
}
template<typename T>
inline Rank vector<T>::search(const T & e) const
{
return search(e, 0, m_size);
}
template<typename T>
inline Rank vector<T>::search(const T & e, Rank lo, Rank hi) const
{
return binSearch(e, lo, hi);
}
template<typename T>
inline int vector<T>::disordered() const
{
int ret = 0;
for (int i = 1; i < m_size; ++i)
{
if (m_data[i - 1] > m_data[i])
++ret;
}
return ret;
}
template<typename T>
inline Rank vector<T>::insert(Rank r, const T & e)
{
assert(r >= 0 && r <= m_size);
expand();
for (Rank i = m_size; i > r; --i)
{
m_data[i] = m_data[i - 1];
}
m_data[r] = e;
++m_size;
return r;
}
template<typename T>
inline Rank vector<T>::insert(const T & e)
{
return insert(m_size, e);
}
template<typename T>
inline const T vector<T>::remove(Rank r)
{
assert(r >= 0 && r < m_size);
T ret = m_data[r];
remove(r, r + 1);
return ret;
}
template<typename T>
inline int vector<T>::remove(Rank lo, Rank hi)
{
assert(lo >= 0 && hi <= m_size && lo < hi);
int ret = hi - lo;
for (Rank i = hi; i < m_size; ++i)
{
m_data[lo++] = m_data[i];
}
m_size -= ret;
shrink();
return ret;
}
template<typename T>
inline void vector<T>::clear()
{
remove(0, m_size);
}
template<typename T>
inline int vector<T>::deduplicate()
{
int old_size = m_size;
for (int i = 1; i < size();)
{
if (find(m_data[i], 0, i) != -1)
remove(i);
else
++i;
}
return old_size - m_size;
}
template<typename T>
inline int vector<T>::uniquify()
{
return uniquify_impl2();
}
template<typename T>
inline void vector<T>::sort(Rank lo, Rank hi)
{
srand(static_cast<unsigned int> (time(nullptr)));
switch (rand() % 5)
{
case 0 :
bubbleSort(lo, hi);
break;
case 1 :
selectSort(lo, hi);
break;
case 2 :
insertSort(lo, hi);
break;
case 3 :
default:
mergeSort(lo, hi);
break;
}
}
template<typename T>
inline void vector<T>::sort()
{
sort(0, m_size);
}
template<typename T>
inline void vector<T>::expand()
{
if (m_size == m_capacity)
{
T *old_data = m_data;
if (m_capacity < DEFAULT_CAPACITY)
m_capacity = DEFAULT_CAPACITY;
m_data = new T[m_capacity <<= 1];
copyFrom(old_data, 0, m_size);
delete[] old_data;
}
}
template<typename T>
inline void vector<T>::shrink()
{
if (m_size * 5 < m_capacity)
{
T *old_data = m_data;
m_capacity = (m_capacity / 2 < DEFAULT_CAPACITY) ? DEFAULT_CAPACITY : (m_capacity >> 1);
m_data = new T[m_capacity];
for (int i = 0; i < m_size; ++i)
m_data[i] = old_data[i];
delete[] old_data;
}
}
template<typename T>
inline void vector<T>::bubbleSort(Rank lo, Rank hi)
{
assert(lo >= 0 && hi <= m_size && lo < hi);
bool sorted = false;
while (!sorted)
{
sorted = true;
for (Rank i = lo + 1; i < hi; ++i)
{
if (m_data[i - 1] > m_data[i])
{
swap(m_data[i - 1], m_data[i]);
sorted = false;
}
}
--hi;
}
}
template<typename T>
inline void vector<T>::selectSort(Rank lo, Rank hi)
{
assert(lo >= 0 && hi <= m_size);
for (int i = 0; i < m_size; ++i)
{
T min = m_data[i];
Rank min_idx = i;
for (int j = i + 1; j < m_size; ++j)
{
if (m_data[j] < min)
{
min = m_data[j];
min_idx = j;
}
}
swap(m_data[min_idx], m_data[i]);
}
}
template<typename T>
inline void vector<T>::insertSort(Rank lo, Rank hi)
{
assert(lo >= 0 && hi <= m_size);
for (Rank i = lo + 1; i < hi; ++i)
{
for (Rank j = i; j > lo; --j)
{
if (m_data[j] < m_data[j - 1])
swap(m_data[j], m_data[j - 1]);
else
break;
}
}
}
template<typename T>
inline void vector<T>::mergeSort(Rank lo, Rank hi)
{
assert(lo >= 0 && hi <= m_size);
if (1 < (hi - lo))
{
Rank mid = (hi + lo) >> 1;
mergeSort(lo, mid);
mergeSort(mid, hi);
merge(lo, mid, hi);
}
}
template<typename T>
inline void vector<T>::merge(Rank lo, Rank mid, Rank hi)
{
assert(lo >= 0 && hi <= m_size && lo < mid && mid < hi);
T *A = m_data + lo;
Rank lb = mid - lo;
T *B = new T[lb];
T *C = m_data + mid;
Rank lc = hi - mid;
for (Rank i = 0; i < lb; ++i)
B[i] = A[i];
Rank i = 0;
Rank j = 0;
Rank k = 0;
while ((j < lb) && (k < lc))
{
if (B[j] < C[k])
A[i++] = B[j++];
else
A[i++] = C[k++];
}
if (j >= lb)
{
while (k < lc)
A[i++] = C[k++];
}
if (k >= lc)
{
while (j < lb)
A[i++] = C[j++];
}
delete[] B;
}
template<typename T>
inline Rank vector<T>::binSearch(const T &e, Rank lo, Rank hi) const
{
srand(static_cast<unsigned int> (time(nullptr)));
switch (2)
{
case 0 :
return binSearch_impl1(e, lo, hi);
case 1:
return binSearch_impl2(e, lo, hi);
case 2:
default:
return binSearch_impl3(e, lo, hi);
}
}
template<typename T>
inline Rank vector<T>::binSearch_impl1(const T & e, Rank lo, Rank hi) const
{
assert(lo >= 0 && hi <= m_size);
while (lo < hi)
{
Rank mid = (lo + hi) >> 1;
if (e == m_data[mid])
return mid;
else if (e < m_data[mid])
hi = mid;
else
lo = mid + 1;
}
return -1;
}
template<typename T>
inline Rank vector<T>::binSearch_impl2(const T & e, Rank lo, Rank hi) const
{
assert(lo >= 0 && hi <= m_size);
while (1 < (hi - lo))
{
Rank mid = (hi + lo) >> 1;
if (e < m_data[mid])
hi = mid;
else
lo = mid;
}
return (e == m_data[lo]) ? lo : -1;
}
template<typename T>
inline Rank vector<T>::binSearch_impl3(const T & e, Rank lo, Rank hi) const
{
assert(lo >= 0 && hi <= m_size);
while (lo < hi)
{
Rank mid = (lo + hi) >> 1;
(e < m_data[mid]) ? hi = mid : lo = mid + 1;
}
return --lo;
}
template<typename T>
inline int vector<T>::uniquify_impl1()
{
int ret = 0;
for (Rank i = 0; i < m_size;)
{
Rank j = i + 1;
while (j < m_size)
{
if (m_data[i] == m_data[j])
++j;
break;
}
if (i + 1 != j)
{
ret += remove(i + 1, j);
i = j;
}
else
++i;
}
shrink();
return ret;
}
template<typename T>
inline int vector<T>::uniquify_impl2()
{
Rank i = 0;
Rank j = 0;
while (++j < m_size)
{
if (m_data[i] != m_data[j])
m_data[++i] = m_data[j];
}
m_size = ++i;
shrink();
return j - i;
}
template<typename T>
void vector<T>::copyFrom(const T *data, Rank lo, Rank hi)
{
m_data = new T[m_capacity = (hi - lo) << 1];
m_size = 0;
while (lo < hi)
{
m_data[m_size++] = data[lo++];
}
}
}
测试程序
void test_vector()
{
int a[] = { 23, 2, 12, 44, -21, 44 };
int sz = sizeof(a) / sizeof(int);
MYSTL::vector<int> iv(a, sz);
cout << iv << endl;
cout << "The capacity is " << iv.capacity() << endl;
cout << "The size is " << iv.size() << endl;
MYSTL::vector<int> iv1(iv);
cout << iv << endl;
MYSTL::vector<int> iv11(iv, 0, iv.size() / 2);
cout << iv11 << endl;
MYSTL::vector<int> iv111(a, 0, sz / 2);
cout << iv111 << endl;
cout << "-------------------------------------------" << endl;
MYSTL::vector<string> sv(10, 5, "hello");
cout << "The capacity is " << sv.capacity() << endl;
cout << "The size is " << sv.size() << endl;
for (int i = 0; i < sv.size(); ++i)
cout << "iv[" << i << "] = " << sv[i] << endl;
sv.deduplicate();
cout << "After deduplicate:" << endl;
cout << sv << endl;
MYSTL::vector<int> iv2;
cout << "The capacity is " << iv2.capacity() << endl;
cout << "The size is " << iv2.size() << endl;
if (iv2.empty())
cout << "iv2 is empty" << endl;
cout << "---------------------------------------" << endl;
for (int i = 0; i < 20; ++i)
iv2.insert(i);
cout << "12 is in Rank " << iv2.find(12) << endl;
cout << iv2 << endl;
cout << "After insert: " << endl;
cout << "The capacity is " << iv2.capacity() << endl;
cout << "The size is " << iv2.size() << endl;
iv2.insert(10, 100);
cout << "After insert: " << endl;
cout << iv2 << endl;
cout << "After expand: " << endl;
cout << "The capacity is " << iv2.capacity() << endl;
cout << "The size is " << iv2.size() << endl;
iv2.remove(0);
cout << "After remove Rank 0:" << endl;
cout << iv2 << endl;
cout << "The size is " << iv2.size() << endl;
iv2.remove(3, iv2.size());
cout << "After remove between Rank 3 to end:" << endl;
cout << iv2 << endl;
cout << "The capacity is " << iv2.capacity() << endl;
cout << "The size is " << iv2.size() << endl;
iv2 = iv;
cout << "After assign, iv2 is:" << endl;
cout << iv2 << endl;
cout << "The capacity is " << iv2.capacity() << endl;
cout << "The size is " << iv2.size() << endl;
MYSTL::vector<int> iv3;
cout << "The capacity is " << iv3.capacity() << endl;
cout << "The size is " << iv3.size() << endl;
for (int i = 0; i < 100; ++i)
iv3.push_back(i);
cout << "iv3 is " << endl;
cout << iv3 << endl;
cout << "The capacity is " << iv3.capacity() << endl;
cout << "The size is " << iv3.size() << endl;
for (int i = 0; i < 100; ++i)
iv3.pop_back();
cout << "iv3 is " << endl;
cout << iv3 << endl;
cout << "The capacity is " << iv3.capacity() << endl;
cout << "The size is " << iv3.size() << endl;
int a1[] = { 23, 32, 23, 1, 21, -3, 2, 23, -3, 1, 23 };
int sz1 = sizeof(a1) / sizeof(int);
MYSTL::vector<int> iv4(a1, sz1);
MYSTL::vector<int> iv5(iv4);
cout << "Before sort:" << endl;
cout << iv4 << endl;
cout << "reverse pair is " << iv4.disordered() << endl;
iv4.sort();
cout << "After sort:" << endl;
cout << iv4 << endl;
cout << "reverse pair is " << iv4.disordered() << endl;
cout << "iv5 is " << endl;
cout << iv5 << endl;
iv5.deduplicate();
cout << "After deduplicate" << endl;
cout << iv5 << endl;
iv5.sort();
iv5.uniquify();
cout << "After uniquify" << endl;
cout << iv5 << endl;
cout << iv5.search(20) << endl;
iv5.clear();
cout << "Is empty? " << iv5.empty() << endl;
}