参考:排序算法
选泡插 快归希堆 桶计基
快速排序
被数组下标恶心到了。。。
c数组写法,c数组下标越界是不报错的,涉及递增递减自己写边界吧,宁可冗余
//确定枢纽元
int partition(int arr[], int low, int high) {
int i = low - 1;
int j = high;
int pivot = arr[high];//直接将末尾当初始枢纽元
while (1)
{
while (i<high&&arr[++i] < pivot);//边界!边界!边界
while (j > low&&arr[--j] > pivot);
if (i < j) swap(&arr[i], &arr[j]);
else break;
}
//把枢纽元放到正确位置
swap(&arr[i], &arr[high]);
return i;
}
//快排
void qsort(int arr[], int low, int high) {
if (low < high) {
int mid = partition(arr, low, high);
qsort(arr, low, mid - 1);
qsort(arr, mid + 1, high);
}
}
//快排入口
void quick_sort(int arry[], int n) {
qsort(arry, 0, n - 1);
}
vector 数组
int partition(vector<int>& a, int left, int right) {
int partition = a[right];
int i = left-1;
int j = right ;
while (1) {
while(i<right&&a[++i]<partition){}//同 边界 但是vector好处是越界会报错
while(j>left&&a[--j]>partition){}
if (i < j) swap(a[i], a[j]);
else break;
}
swap(a[i], a[right]);
return i;
}
void quicksort(vector<int>&a, int left, int right) {
if (left < right) {
int mid = partition(a, left, right);
quicksort(a, left, mid - 1);
quicksort(a, mid + 1, right);
}
}
void quicksort(vector<int>& a) {
quicksort(a, 0, a.size() - 1);
}
枢纽元选取为三数中值法 好处是优化了起始随机选数的不确定性 坏处的无法完成小于三个数的排序 综合性能在10个分组下的数使用插入排序
void insertionSort(vector<int>& a, int left,int right) {
for (int p = left + 1; p <= right; ++p)
{
int tmp = std::move(a[p]);
int j;
for (j = p; j > left && tmp < a[j - 1]; --j)
a[j] = std::move(a[j - 1]);
a[j] = std::move(tmp);
}
}
#pragma region quicksort median3
const int& median3(vector<int>& a, int left, int right) {
int center = (left + right) / 2;
if (a[center] < a[left]) swap(a[left], a[center]);
if (a[right] < a[left]) swap(a[right], a[left]);
if (a[right] < a[center]) swap(a[right], a[center]);//使左中右按顺序排列
swap(a[center], a[right - 1]);//将节点放到right-1;right本身>center
return a[right - 1];
}
void quickSort(vector<int> &a, int left, int right) {
if (left+10<= right) {
const int& center = median3(a, left, right);
int i = left, j = right - 1;
while (1) {
while (center > a[++i]) {}//先递增、递减
while (a[--j]>center) {}
if (i < j) swap(a[i], a[j]);
else break;
}
swap(a[i], a[right - 1]);//归位
quickSort(a, left, i - 1);//递归
quickSort(a, i + 1, right);
}
else insertionSort(a, left, right);
}
void quickSort(vector<int>& a)
{
quickSort(a,0,a.size()-1);
}
当然想不加插入排序也是可以的 边界搞好。。。(orz)
void quickSort(vector<int> &a, int left, int right) {
if (left< right) {
const int& center = median3(a, left, right);
int i = left, j = right - 1;
while (1) {
while (i<right-1&¢er > a[++i]) {}//先递增、递减
while (j>0 && a[--j]>center) {}
if (i < j) swap(a[i], a[j]);
else break;
}
swap(a[i], a[right - 1]);//归位
quickSort(a, left, i - 1);//递归
quickSort(a, i + 1, right);
}
//else insertionSort(a, left, right);
}
堆排序
从底向上的构建大顶堆
int leftChild(int i) {
return 2 * i + 1;
}
void perDown(vector<int> &a, int i, int n) {
int child;
int tmp;
for (tmp = a[i]; leftChild(i) < n; i = child) {
child = leftChild(i);
if (child != n - 1 && a[child] < a[child + 1]) ++child;
if (tmp < a[child]) a[i] = move(a[child]);
else break;
}
a[i] = tmp;
//print_arr(a);
}
void heapsort(vector<int> a) {
for (int i = a.size() / 2 - 1; i >= 0; i--)
perDown(a, i, a.size()); //build heap
for (int j = a.size() - 1; j > 0; --j) {
swap(a[0], a[j]);
perDown(a, 0, j); //deleteMax
}
}
归并排序
稳定 nlogn
类似合并有序链表
void merge(vector<int> &a, vector<int> &tmpArray, int leftPos, int rightPos, int rightEnd) {
int leftEnd = rightPos - 1;
int tmpPos = leftPos;
int numElements = rightEnd - leftPos + 1;
while (leftPos <= leftEnd&&rightPos <= rightEnd) {
if (a[leftPos] <= a[rightPos]) tmpArray[tmpPos++] = move(a[leftPos++]);
else tmpArray[tmpPos++] = move(a[rightPos++]);
}
while (leftPos <= leftEnd)
tmpArray[tmpPos++]= move(a[leftPos++]);
while (leftPos <= rightEnd)
tmpArray[tmpPos++] = move(a[rightPos++]);
for (int i = 0; i < numElements; ++i, --rightEnd)
a[rightEnd] = move(tmpArray[rightEnd]);
}
void mergeSort(vector<int> &a, vector<int> &tmpArray, int left, int right) {
if (left < right) {
int center = (left + right) / 2;
mergeSort(a, tmpArray, left, center);
mergeSort(a, tmpArray, center + 1, right);
merge(a, tmpArray, left, center + 1, right);
}
}
void mergeSort(vector<int>& a){
vector<int> tmpArray(a.size());
mergeSort(a, tmpArray, 0, a.size() - 1);
}
冒泡排序
稳定 n2
void bubblesort(vector<int>& a) {
int n = a.size();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n - 1 - i; j++) {
if (a[j] > a[j + 1]) swap(a[j], a[j + 1]);
}
}
}
插入排序
稳定
void insertsort(vector<int> a) {
int n = a.size();
for (int i = 1; i < n; i++) {
int tmp = move(a[i]);
int j;
for (j = i; j >0&&tmp<a[j-1]; j--) {
a[j] = move(a[j - 1]);
}
a[j] = move(tmp);
}
}
希尔排序
void shellsort(vector<int>& a) {
for (int gap = a.size() / 2; gap > 0; gap /= 2) {
for (int i = gap; i < a.size(); ++i) {
int tmp = move(a[i]);
int j = i;
for (; j >= gap&&tmp < a[j - gap]; j -= gap) {
a[j] = move(a[j - gap]);
}
a[j] = move(tmp);
}
}
}
选择排序
void selectsort(vector<int>& a) {
int n = a.size();
for (int i = 0; i < n-1; i++) {
int swappos = i;
for (int j = i + 1; j < n; j++) {
if (a[swappos] > a[j]) swappos = j;
}
if (swappos != i) swap(a[i], a[swappos]);
}
}