各种排序的思想
排序
各种排序的实现及复杂度
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include "lan.h"
using namespace std;
void InsertSort(int* a, int n) {
for (int i = 0; i < n - 1; i++) {
int j = i, key = a[i+1];
while (j >= 0 && a[j] > key) {
a[j+1] = a[j];
j--;
}
a[j+1] = key;
}
}
void ShellSort(int* a, int n){
int gap = n;
while (gap > 1) {
gap = gap / 3 + 1;
for (int i = 0; i < n - gap; i++) {
int j = i, key = a[i + gap];
while (j >= 0 && a[j] > key) {
a[j + gap] = a[j];
j -= gap;
}
a[j+gap] = key;
}
}
}
void SelectSort(int* a, int n)
{
for (int i = 0; i < n / 2; i++) {
int begin = i, end = n - i - 1;
int min = i, max = i;
for (int j = i + 1; j <= end; j++) {
if (a[j] >= a[max])
max = j;
if (a[j] < a[min])
min = j;
}
a[begin] = a[min];
a[end] = a[max];
}
}
void AdjustDown(int* a, int n, int root)
{
int parent = root;
int child = parent * 2 + 1;
while (child < n) {
if (child + 1 < n
&& a[child + 1] > a[child]) {
++child;
}
if (a[child] > a[parent]) {
Swap(&a[child], &a[parent]);
parent = child;
child = parent * 2 + 1;
}
else {
break;
}
}
}
void HeapSort(int* a, int n)
{
for (int i = (n - 2) / 2; i >= 0; --i)
{
AdjustDown(a, n, i);
}
int end = n - 1;
while (end > 0)
{
swap(a[0], a[end]);
AdjustDown(a, end, 0);
--end;
}
}
void BubbleSort(int* a, int n) {
for (int i = 0; i < n - 1; i++) {
for (int j = n - 1; j > 0; j--) {
if (a[j - 1] > a[j])
swap(a[j - 1], a[j]);
}
}
}
int PartSort1(int* a, int left, int right)
{
int begin = left, end = right;
int key = a[left];
while (begin < end) {
while (begin < end && a[end] >= key)
end--;
while (begin < end && a[begin] <= key)
begin++;
swap(a[begin], a[end]);
}
swap(a[left], a[begin]);
return begin;
}
int PartSort2(int* a, int left, int right)
{
int begin = left, end = right;
int key = a[left];
while (begin < end) {
while (begin < end && a[end] >= key)
end--;
a[begin] = a[end];
while (begin < end && a[begin] <= key)
begin++;
a[end] = a[begin];
}
a[begin] = key;
return begin;
}
int PartSort3(int* a, int left, int right)
{
int begin = left, end = left+1;
int key = a[left];
while (end <= right) {
while (a[end] < key && ++begin != end)
swap(a[begin], a[end]);
end++;
}
swap(a[left], a[begin]);
return begin;
}
void QuickSort(int* a, int left, int right)
{
if (left >= right)
return;
int mid = PartSort3(a, left, right);
PartSort3(a, left, mid - 1);
PartSort3(a, mid + 1, right);
}
void QuickSortNonR_Queue(int* a, int left, int right)
{
queue<int> Q;
if (left >= right)
return;
Q.push(left);
Q.push(right);
while (!Q.empty()) {
int new_left = Q.front();
Q.pop();
int new_right = Q.front();
int begin = new_left, end = new_right;
Q.pop();
if (begin >= end)
continue;
int key = a[begin];
while (begin < end) {
while (begin < end && a[end] >= key)
end--;
a[end] = a[begin];
while (begin < end && a[begin] <= key)
begin++;
a[begin] = a[end];
}
swap(a[new_left], a[begin]);
Q.push(new_left);
Q.push(begin - 1);
Q.push(begin + 1);
Q.push(new_right);
}
}
void QuickSortNonR_Stack(int* a, int left, int right)
{
stack<int> S;
if (left < right) {
S.push(left);
S.push(right);
}
while (!S.empty()) {
int end = S.top();
S.pop();
int begin = S.top();
S.pop();
int div = PartSort2(a, begin, end);
if (begin < div - 1) {
S.push(begin);
S.push(div-1);
}
if (end > div + 1) {
S.push(div + 1);
S.push(end);
}
}
}
void merge(int* a, int left, int right, int* tmp)
{
if (left >= right)
return;
int mid = left + ((right - left) >> 1);
merge(a, left, mid, tmp);
merge(a, mid + 1, right, tmp);
int begin1 = left, end1 = mid;
int begin2 = mid + 1, end2 = right;
int idx = left;
while (begin1 <= end1 && begin2 <= end2) {
if (a[begin1] >= a[begin2])
tmp[idx++] = a[begin2++];
else
tmp[idx++] = a[begin1++];
}
while (begin1 <= end1)
tmp[idx++] = a[begin1++];
while (begin2 <= end2)
tmp[idx++] = a[begin2++];
memcpy(a + left, tmp + left, (right - left + 1)*4);
}
void MergeSort(int* a, int n)
{
int* tmp = (int*)malloc(sizeof(int)*n);
merge(a, 0, n - 1, tmp);
free(tmp);
}
void mergeNorR(int* a, int left, int mid, int right, int* tmp)
{
int begin1 = left, end1 = mid;
int begin2 = mid + 1, end2 = right;
int idx = left;
while (begin1 <= end1 && begin2 <= end2) {
if (a[begin1] >= a[begin2])
tmp[idx++] = a[begin2++];
else
tmp[idx++] = a[begin1++];
}
while (begin1 <= end1)
tmp[idx++] = a[begin1++];
while (begin2 <= end2)
tmp[idx++] = a[begin2++];
memcpy(a + left, tmp + left, (right - left + 1) * 4);
}
void mergePass(int *arr, int k, int n, int *temp)
{
int i = 0;
while (i < n - 2 * k + 1)
{
mergeNorR(arr, i, i + k - 1, i + 2 * k - 1, temp);
i += 2 * k;
}
if (i < n - k)
{
mergeNorR(arr, i, i + k - 1, n - 1, temp);
}
}
void MergeSortNonR(int *arr, int length)
{
int k = 1;
int *temp = (int *)malloc(sizeof(int) * length);
while (k < length)
{
mergePass(arr, k, length, temp);
k *= 2;
}
free(temp);
}
void CountSort(int* a, int n)
{
int max = 0, min = 0;
for (int i = 1; i < n; i++) {
if (a[i] > a[max])
max = i;
if (a[i] < a[min])
min = i;
}
int m = a[max] - a[min] + 1;
int* tmp = (int*)malloc(sizeof(int) * m);
memset(tmp, 0, sizeof(int) * m);
for (int i = 0; i < n; i++) {
tmp[a[i] - a[min]]++;
}
int idx = 0, key = a[min];
for (int i = 0; i < m; i++) {
while (tmp[i]) {
a[idx++] = key + i;
tmp[i]--;
}
}
}