1.Vector.h模板类的实现
- 最近复习数据结构,顺便把Vector.h模板类实现了,同时也再实现了一遍十种排序算法,具体包括了Vector的构造函数与多种功能函数,以及内置的十种排序算法与乱序器。
#pragma once
#include <time.h>
#include <list>
#include <vector>
#include <queue>
using namespace std;
template<typename T> class Vector
{
private:
int _size;
int _capacity;
T* _elem;
public:
Vector(int capacity = 1, T value = 0);
Vector(const Vector<T>& vec);
Vector(Vector<T>&& vec) noexcept;
Vector<T>& operator=(const Vector<T>& vec);
Vector<T>& operator=(Vector<T>&& vec) noexcept;
T& operator[](int rank) const;
~Vector();
void shrink();
void expand();
bool empty() const;
int size() const;
int find(T const& v);
int find(T const& v, int lo, int hi);
int erase(int rank);
int erase(int lo, int hi);
int insert(int rank, T const&v);
void print(int lo, int hi);
void unsort();
void sort();
void sort(int lo, int hi);
void bubblesort(int lo, int hi);
void mergesort(int lo, int hi);
void merge(int lo, int mi, int hi);
void insertionsort(int lo, int hi);
void selectionsort(int lo, int hi);
void countingsort(int lo, int hi);
void bucketsort(int lo, int hi);
void radixsort(int lo, int hi);
void moveDown(int first, int last);
void moveUp(int rank);
void moveDown_reserve(int first, int last);
void heapsort(int lo, int hi);
void quicksort(int lo, int hi);
int partition(int lo, int hi);
void shellsort(int lo, int hi);
};
#include "Vector.h"
#include <random>
template<typename T> Vector<T>::Vector(int capacity = 1, T value = 0)
{
_elem = new T[_capacity = capacity];
for (_size = 0; _size < _capacity; _size++)
_elem[_size] = value;
}
template<typename T> Vector<T>::Vector(const Vector& vec)
{
_elem = new T[_capacity = vec._capacity];
for (_size = 0; _size < vec._size; _size++)
_elem[_size] = vec[_size];
}
template<typename T> Vector<T>::Vector(Vector&& vec) noexcept
{
_elem = vec._elem;
_size = vec._size;
_capacity = vec._capacity;
vec._elem = nullptr;
vec._size = vec._capacity = 0;
}
template<typename T> Vector<T>& Vector<T>::operator=(const Vector<T>& vec)
{
if (this != &vec)
{
delete[] _elem;
_elem = new T[_capacity = vec._capacity];
for (_size = 0; _size < vec._size; _size++)
_elem[_size] = vec[_size];
}
return *this;
}
template<typename T> Vector<T>& Vector<T>::operator=(Vector&& vec) noexcept
{
if (this != &vec)
{
delete[] _elem;
_elem = vec._elem;
_size = vec._size;
_capacity = vec._capacity;
vec._elem = nullptr;
vec._size = vec._capacity = 0;
}
return *this;
}
template<typename T> T& Vector<T>::operator[](int rank) const
{
return _elem[rank];
}
template<typename T> Vector<T>::~Vector()
{
delete[] _elem;
}
template<typename T> void Vector<T>::expand()
{
if (_size < _capacity)
return;
else
{
T* _oldelem = _elem;
_elem = new T[_capacity <<= 1];
for (int i = 0; i < _size; i++)
_elem[i] = _oldelem[i];
delete[] _oldelem;
}
}
template<typename T> void Vector<T>::shrink()
{
if (_size << 2 > _capacity)
return;
else
{
T* _oldelem = _elem;
_elem = new T[_capacity >>= 1];
for (int i = 0; i < _size; i++)
_elem[i] = _oldelem[i];
delete[] _oldelem;
}
}
template<typename T> bool Vector<T>::empty() const
{
return !_size;
}
template<typename T> int Vector<T>::size() const
{
return _size;
}
template<typename T> int Vector<T>::find(T const& v)
{
find(v, 0, _size);
}
template<typename T> int Vector<T>::find(T const& v, int lo, int hi)
{
while (lo < hi && v != _elem[lo])
lo++;
return (lo == hi) ? (-1) : (lo);
}
template<typename T> int Vector<T>::erase(int rank)
{
return erase(rank, rank + 1);
}
template<typename T> int Vector<T>::erase(int lo, int hi)
{
if (lo == hi)
return 0;
while (hi < _size)
_elem[lo++] = _elem[hi++];
_size = lo;
shrink();
return hi - lo;
}
template<typename T> int Vector<T>::insert(int rank, T const&v)
{
expand();
for (int i = _size; i > rank; i--)
_elem[i] = _elem[i - 1];
_elem[rank] = v;
_size++;
return rank;
}
template<typename T> void Vector<T>::print(int lo, int hi)
{
while (lo < hi)
std::cout << _elem[lo++] << " ";
std::cout << std::endl;
}
template<typename T> void Vector<T>::unsort()
{
for (int i = _size; i > 0; i--)
{
srand((unsigned)time(NULL));
swap(_elem[i - 1], _elem[rand() % i]);
}
}
template<typename T> void Vector<T>::sort()
{
sort(0, _size);
}
template<typename T> void Vector<T>::sort(int lo, int hi)
{
srand((unsigned)time(NULL));
int n = 9;
switch (n)
{
case 0: bubblesort(lo, hi); cout << "当前使用bubblesort" << endl; break;
case 1: mergesort(lo, hi); cout << "当前使用mergesort" << endl; break;
case 2: insertionsort(lo, hi); cout << "当前使用insertionsort" << endl; break;
case 3: selectionsort(lo, hi); cout << "当前使用selectionsort" << endl; break;
case 4: countingsort(lo, hi) ; cout << "当前使用countingsort" << endl; break;
case 5: bucketsort(lo, hi); cout << "当前使用bucketsort" << endl; break;
case 6: radixsort(lo, hi); cout << "当前使用radixsort" << endl; break;
case 7: heapsort(lo, hi); cout << "当前使用heapsort" << endl; break;
case 8: quicksort(lo, hi); cout << "当前使用quicksort" << endl; break;
case 9: shellsort(lo, hi); cout << "当前使用shellsort" << endl; break;
default: break;
}
}
template<typename T> void Vector<T>::bubblesort(int lo, int hi)
{
bool flag = false;
while (!flag)
{
flag = true;
for (int i = lo; i < hi - 1; i++)
{
if (_elem[i] > _elem[i + 1])
{
swap(_elem[i], _elem[i + 1]);
flag = false;
}
}
hi--;
}
}
template<typename T> void Vector<T>::mergesort(int lo, int hi)
{
if (hi - lo < 2)
return;
int mi = (hi + lo) >> 1;
mergesort(lo, mi);
mergesort(mi, hi);
merge(lo, mi, hi);
}
template<typename T> void Vector<T>::merge(int lo, int mi, int hi)
{
int i1 = 0, i2 = lo, i3 = mi;
int *temp = new int[hi - lo];
while (i2 < mi && i3 < hi)
{
if (_elem[i2] <= _elem[i3])
temp[i1++] = _elem[i2++];
else
temp[i1++] = _elem[i3++];
}
while (i2 < mi)
temp[i1++] = _elem[i2++];
while (i3 < hi)
temp[i1++] = _elem[i3++];
for (int i = 0; i < hi - lo; i++)
_elem[i + lo] = temp[i];
delete[] temp;
}
template<typename T> void Vector<T>::insertionsort(int lo, int hi)
{
for (int i = lo + 1, j; i < hi; i++)
{
for (j = i; j > lo && _elem[j] < _elem[j - 1]; j--)
swap(_elem[j], _elem[j - 1]);
}
}
template<typename T> void Vector<T>::selectionsort(int lo, int hi)
{
for (int i = hi - 1, j, max; i > lo; i--)
{
for (j = lo, max = i; j <= i; j++)
if (_elem[j] > _elem[max])
max = j;
if (i != max)
swap(_elem[i], _elem[max]);
}
}
template<typename T> void Vector<T>::countingsort(int lo, int hi)
{
int largest = _elem[lo];
int minest = _elem[lo];
for (int i = lo; i < hi; i++)
{
if (_elem[i] > largest)
largest = _elem[i];
if (_elem[i] < minest)
minest = _elem[i];
}
int size = largest - minest + 1;
int *bucket = new int[size];
for (int i = 0; i < size; i++)
bucket[i] = 0;
for (int i = lo; i < hi; i++)
bucket[_elem[i] - minest]++;
for (int i = 0; i < size;)
{
if (bucket[i]-- > 0)
_elem[lo++] = i + minest;
else
i++;
}
delete[] bucket;
}
template<typename T> void Vector<T>::bucketsort(int lo, int hi)
{
int largest = _elem[lo];
int minest = _elem[lo];
for (int i = lo; i < hi; i++)
{
if (_elem[i] > largest)
largest = _elem[i];
if (_elem[i] < minest)
minest = _elem[i];
}
int n = 5;
vector<vector<int>> bucket(n + 1);
int range = (largest - minest) / n;
if (range < 1) range = 1;
for (int i = lo; i < hi; i++)
{
int index = (_elem[i] - minest) / range;
bucket[index].push_back(_elem[i]);
for (int j = bucket[index].size() - 1; j > 0 && bucket[index][j] < bucket[index][j - 1]; j--)
swap(bucket[index][j], bucket[index][j - 1]);
}
int cur = lo;
for (int i = 0; i <= n; i++)
for (int j = 0; j < bucket[i].size(); j++)
_elem[cur++] = bucket[i][j];
}
template<typename T> void Vector<T>::radixsort(int lo, int hi)
{
int i, j, k, factor;
const int radix = 10;
const int digits = 10;
queue<T> queues[radix];
for (i = 0, factor = 1; i < digits; factor *= radix, i++)
{
for (j = lo; j < hi; j++)
queues[(_elem[j] / factor) % radix].push(_elem[j]);
for (j = 0, k = lo; j < radix; j++)
while (!queues[j].empty())
{
_elem[k++] = queues[j].front();
queues[j].pop();
}
}
}
template<typename T> void Vector<T>::moveDown(int first, int last)
{
int largest = 2 * first + 1;
while (largest <= last)
{
if (largest < last && _elem[largest] < _elem[largest + 1])
largest++;
if (_elem[first] < _elem[largest])
{
swap(_elem[first], _elem[largest]);
first = largest;
largest = 2 * first + 1;
}
else
break;
}
}
template<typename T> void Vector<T>::moveUp(int rank)
{
int parent_rank = (rank >> 1) - 1;
while (parent_rank >= 0)
{
if (_elem[rank] <= _elem[parent_rank])
break;
swap(_elem[rank], _elem[parent_rank]);
rank = parent_rank;
parent_rank = (rank >> 1) - 1;
}
}
template<typename T> void Vector<T>::moveDown_reserve(int first, int last)
{
int largest = 2 * first + 1;
while (largest <= last)
{
if (largest < last && _elem[largest] > _elem[largest + 1])
largest++;
if (_elem[first] > _elem[largest])
{
swap(_elem[first], _elem[largest]);
first = largest;
largest = 2 * first + 1;
}
else
break;
}
}
template<typename T> void Vector<T>::heapsort(int lo, int hi)
{
for (int i = ((hi - lo) >> 1) - 1; i >= lo; --i)
moveDown(i, hi - lo - 1);
cout << "建堆后数组为: ";
for (int i = lo; i < hi - lo; i++)
cout << _elem[i] << " ";
cout << endl;
for (int i = hi - lo - 1; i >= lo + 1; --i)
{
swap(_elem[lo], _elem[i]);
moveDown(lo, i - 1);
}
}
template<typename T> void Vector<T>::quicksort(int lo, int hi)
{
if (hi - lo < 2)
return;
int mi = partition(lo, hi - 1);
quicksort(lo, mi);
quicksort(mi + 1, hi);
}
template<typename T> int Vector<T>::partition(int lo, int hi)
{
int pivot = _elem[lo];
while (lo < hi)
{
while (lo < hi && pivot <= _elem[hi])
hi--;
_elem[lo] = _elem[hi];
while (lo < hi && pivot >= _elem[lo])
lo++;
_elem[hi] = _elem[lo];
}
_elem[lo] = pivot;
return lo;
}
template<typename T> void Vector<T>::shellsort(int lo, int hi)
{
list<T> increment;
int size = hi - lo;
int temp = 0;
while (temp < (size / 3))
increment.push_front(temp = (temp * 3 + 1));
for (auto &h : increment)
{
for (int hh = lo + h; hh < lo + 2 * h; hh++)
{
for (int i = hh; i < hi; i += h)
{
for (int j = i; j >= lo + h && _elem[j] < _elem[j - h]; j -= h)
swap(_elem[j], _elem[j - h]);
}
}
}
}