// 11类常用算法代码实现
//
#include <iostream>
#include<vector>
using namespace std;
//1.直接插入排序 O(n^2)
template<class T>
void Insert(vector<T>* a)
{
size_t N = (*a).size();
for (int i = 1; i < N; i++)
{
if ((*a)[i] < (*a)[i - 1])
{
int j = i - 1;
T tmp = (*a)[i];
while (j >= 0 && tmp < (*a)[j])
{
(*a)[j + 1] = (*a)[j];
j--;
}
(*a)[j + 1] = tmp;
}
}
}
//2.折半插入排序
template<class T>
void BInsert(vector<T>* a)
{
size_t N = (*a).size();
for (int i = 1; i < N; i++)
{
if ((*a)[i] < (*a)[i - 1])
{
int low = 0, high = i - 1,mid;
T tmp = (*a)[i];
while (low <= high)
{
mid = (low + high) / 2;
if ((*a)[mid] > tmp) high = mid - 1;
else low = mid + 1;
}
// 有序表中插入位置后的元素都后移一步
for (int j = i; j > low; j--) (*a)[j] = (*a)[j - 1];
(*a)[low] = tmp;
}
}
}
//3. 2路插入排序
template<class T>
void Insert2(vector<T>* a)
{
size_t N = (*a).size();
vector<T> d(N);
int start, end;
start = end = 0;
d[0] = (*a)[0];
for (int i = 1; i < N; i++)
{
if ((*a)[i] < d[start])
{
start = (start - 1 + N) % N;
d[start] = (*a)[i];
}
else if ((*a)[i] > d[end])
{
end = (end + 1 + N) % N;
d[end] = (*a)[i];
}
else
{
int k= (end + 1 + N) % N;
while (d[(k - 1 + N) % N] > (*a)[i])
{
d[(k + N) % N] = d[(k - 1 + N) % N];
k = (k - 1 + N) % N;
}
d[(k + N) % N] = (*a)[i];
end = (end + 1 + N) % N;
}
}
for (int i = 0; i < N; i++)
{
(*a)[i] = d[(start + i) % N];
}
}
template<class T>
void printAns(vector<T> a)
{
for (auto elem : a) cout << elem << " ";
cout << endl;
}
template<class T>
void swap(T* a, T* b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
//4.冒泡排序
template<class T>
void bubble(vector<T>* a)
{
int N = (*a).size();
for (int i = 0; i < N; i++)
{
bool flag = true;
for (int j = 0; j < N - i - 1; j++)
{
if ((*a)[j] > (*a)[j + 1])
{
flag = false;
swap(&(*a)[j], &(*a)[j + 1]);
}
}
if (flag) break;
}
}
// 分割操作
template<class T>
int partition(vector<T>* a,int low,int high)
{
int pivot = (*a)[low];//支点
while (low < high)
{
while (low < high && (*a)[high] >= pivot)
{
high--;
}
swap(&(*a)[low], &(*a)[high]);
while (low < high && (*a)[low] <= pivot)
{
low++;
}
swap(&(*a)[low], &(*a)[high]);
}
return low;
}
template<class T>
void qSort(vector<T>* a,int low,int high)
{
if (low < high)
{
int pivot = partition(a, low, high);
qSort(a, low, pivot - 1);
qSort(a, pivot + 1, high);
}
}
//6.快排
template<class T>
void qSort(vector<T>* a)
{
qSort(a, 0, (*a).size() - 1);
}
//找最小值所在下标
template<class T>
int minIdx(vector<T>* a, int idx)
{
int min = idx;
int N = (*a).size();
for (int i = idx + 1; i < N; i++)
{
if ((*a)[min] > (*a)[i]) min = i;
}
return min;
}
//7.选择排序
template<class T>
void selectSort(vector<T>* a)
{
int N = (*a).size();
for (int i = 0; i < N; i++)
{
int idx = minIdx(a, i);
if (i != idx) swap((*a)[i], (*a)[idx]);
}
}
template<class T>
int selectMin(vector<T> *a, vector<int> record)
{
if (record.size() == 1)
{
return record.back();
}
int N = record.size();
vector<int> halfRecord;
N = N / 2;
int tmp;
for (int i = 0; i < N; i++)
{
tmp = record[2 * i];
if ((*a)[record[2 * i]] > (*a)[record[2 * i + 1]])
{
tmp = record[2 * i + 1];
}
halfRecord.push_back(tmp);
}
if (record.size() % 2 == 1)
{
halfRecord.push_back(record.back());
}
return selectMin(a, halfRecord);
}
// 8.树型选择排序
template<class T>
void treeSort(vector<T>* a)
{
vector<int> record;
vector<T> tmp(*a);
for (int i = 0; i < (*a).size(); i++)
{
record.push_back(i);
}
for (int i = 0; i < (*a).size(); i++)
{
int idx= selectMin(&tmp, record);
(*a)[i] = tmp[idx];
tmp[idx] = INT_MAX;
}
}
template<class T>
void adjust(vector<T>* a, int s,int N)
{
T rc = (*a)[s];
for (int i = 2 * s + 1; i < N; i = i * 2 + 1)
{
if (i + 1 < N && (*a)[i] < (*a)[i + 1]) i++;
if (rc >=(*a)[i]) break; // 无需调整
(*a)[s] = (*a)[i];
s = i;
}
(*a)[s] = rc;
}
//9.堆排序
template<class T>
void heapSort(vector<T>* a)
{
int N = (*a).size();
//构建堆
for (int i = (*a).size() / 2; i >= 0; i--)
{
adjust(a, i,N);
}
//调整剩余元素构建一个新堆
for (int i = (*a).size()-1; i >=0; i--)
{
swap(&(*a)[0], &(*a)[i]);
adjust(a, 0,i-1);
}
}
//10.归并排序
template<class T>
void mergeSort(vector<T>* a, int lo, int hi,int mid)
{
vector<T> tmp(hi - lo + 1); // 存放需要归并排序的数组
int i, j, k;
for (k = lo; k <= hi; k++)
{
tmp[k - lo] = (*a)[k];
}
i = lo; // 左半边
j = mid + 1; // 右半边
for (k = lo; k <= hi; k++)
{
if (i > mid) // 只有右半边有用
{
(*a)[k] = tmp[j - lo];
j++;
}
else if (j > hi) // 只有左半边有用
{
(*a)[k] = tmp[i - lo];
i++;
}
else if (tmp[i - lo] > tmp[j - lo]) // 右边更小
{
(*a)[k] = tmp[j - lo];
j++;
}
else // 左边更小
{
(*a)[k] = tmp[i - lo];
i++;
}
}
}
template<class T>
void mergeSort(vector<T>* a,int lo,int hi)
{
if (lo >= hi) return;
int mid = (lo + hi) / 2;
mergeSort(a, lo, mid);
mergeSort(a, mid + 1, hi); // 相当于是后续遍历,从左右到根
mergeSort(a, lo, hi, mid);
}
template<class T>
void mergeSort(vector<T>* a)
{
mergeSort(a, 0, (*a).size()-1);
}
//11.基数排序
template<class T>
void distruib(vector<T>* a,int digit)// 分配和收集算法
{
vector<vector<T>> tmp(10);
int s = pow(10, digit-1);
int elem;
for(int i=0;i<(*a).size();i++)
{
elem = (*a)[i] / s;
elem = elem % 10;
tmp[elem].push_back((*a)[i]);
}
int idx = 0;
for (auto vec : tmp)
{
for (int i = 0; i < vec.size(); i++)
{
(*a)[idx++] = vec[i];
}
}
}
template<class T>
int maxDigit(vector<T>* a) // 最大位数
{
int maxElem = (*a).front();
for(int i=1;i<(*a).size();i++)
{
if ((*a)[i] > maxElem) maxElem = (*a)[i];
}
int ret = 0;
while (maxElem > 0)
{
maxElem = maxElem / 10;
ret++;
}
return ret;
}
template<class T>
void radixSort(vector<T>* a)
{
int num=maxDigit(a);//循环次数
for (int i = 1; i <= num; i++)
{
distruib(a, i);
}
return;
}
int main()
{
//vector<int> ArrDirInser{ 3,1,7,5,2,4,9,6 };
vector<int> ArrDirInser{50,123,543,187,49,30,0,2,11,100};
//1.
//Insert(&ArrDirInser);
//BInsert(&ArrDirInser);
//Insert2(&ArrDirInser);
//bubble(&ArrDirInser);
//qSort(&ArrDirInser);
//selectSort(&ArrDirInser);
//treeSort(&ArrDirInser);
//heapSort(&ArrDirInser);
//mergeSort(&ArrDirInser);
radixSort(&ArrDirInser);
printAns(ArrDirInser);
std::cout << "Hello World!\n";
}
常用排序算法总结
最新推荐文章于 2022-03-17 10:46:00 发布