void Swap(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
//插入排序
//1、直接插入排序 - 从前往后比较
void InsertSort_1(int* ar, int left, int right)
{
for (int i = left + 1; i < right; i++)
{
int k = left;
while (ar[k] <= ar[i])
k++;
int tmp = ar[i];
int j = i;
for (j; j > k; j--)
ar[j] = ar[j - 1];
ar[j] = tmp;
}
}
//2、直接插入排序 -- 从后往前比较
void InsertSort_2(int* ar, int left, int right)
{
for (int i = left + 1; i < right; i++)
{
for (int j = i; j > left; j--)
{
if (ar[j - 1] > ar[j])
Swap(&ar[j - 1], &ar[j]);
}
}
}
//3、直接插入排序 -- 从后往前比较,不调用交换函数
void InsertSort_3(int* ar, int left, int right)
{
for (int i = left + 1; i < right; i++)
{
int tmp = ar[i];
int j = i;
while (j > left && ar[j - 1] > tmp)
{
ar[j] = ar[j - 1];
j--;
}
ar[j] = tmp;
}
}
//4、直接插入排序 -- 从后往前比较,带哨兵位
void InsertSort_4(int* ar, int left, int right)
{
for (int i = left + 1; i < right; i++)
{
ar[0] = ar[i];
int k = i;
while (ar[k - 1] > ar[0])
{
ar[k] = ar[k-1];
k--;
}
ar[k] = ar[0];
}
}
//5、折半插入排序
void BinInsertSort(int* ar, int left, int right)
{
for (int i = left + 1; i < right; i++)
{
int tmp = ar[i];
int low = left;
int high = i-1;
while (low <= high)
{
int mid = (low + high)/2;
if (tmp >= ar[mid])
low = mid + 1;
else
high = mid - 1;
}
for(int j = i; j > low; j--)
ar[j] = ar[j - 1];
ar[low] = tmp;
}
}
//Shell排序
void _ShellSort(int* ar, int left, int right, int gap)
{
for (int i = left + gap; i < right; ++i)
{
int tmp = ar[i];
int j = i;
while (j > left && tmp < ar[j - gap])
{
ar[j] = ar[j - gap];
j -= gap;
}
ar[j] = tmp;
}
}
//分组
void _ShellSort(int* ar, int left, int right)
{
int dlta[] = { 5,3,2,1 }; //素数
int n = sizeof(dlta) / sizeof(dlta[0]);
for (int i = 0; i < n; ++i)
{
_ShellSort(ar, left, right, dlta[i]);
}
}
//Shell排序
void ShellSort(int* ar, int left, int right)
{
int gap = right - left;
while (gap > 1)
{
gap = gap / 3 + 1;//...5 3 2 1
for (int i = left + gap; i < right; i++)
{
if (ar[i] < ar[i - gap])
{
int tmp = ar[i];
int j = i;
while(j > left&& tmp < ar[j - gap])
{
ar[j]=ar[j - gap];
j = j - gap;
}
ar[j] = tmp;
}
}
}
}
//选择排序
//简单选择排序
//寻找最小值下标
int GetMinIndex(int* ar, int left, int right)
{
int index = 0;
int min_value = ar[left];
for (int i = left; i < right; i++)
{
if (ar[i] <=min_value )
{
min_value = ar[i];
index = i;
}
}
return index;
}
void SelectSort(int* ar, int left, int right)
{
for (int i = left; i < right; i++)
{
int index = GetMinIndex(ar, i, right);
if (index != i)
{
int tmp = ar[i];
ar[i] = ar[index];
ar[index] = tmp;
}
}
}
//堆排
//向下调整
void _AdjustDownByHeapSort(int* ar, int left, int right, int start)
{
int n = right - left;
int i = start;
//找左子树
int j = 2 * i + 1;
int tmp = ar[i];
while (j < n)
{
if (ar[j + 1] < n && ar[j] < ar[j + i])
j++;
if (ar[j] > tmp)
{
ar[i] = ar[j];
i = j;
j = 2 * i + 1;
}
else
break;
}
ar[i] = tmp;
}
void HeapSort(int* ar, int left, int right)
{
//建堆(从小到大排序,建大堆)
int n = right - left;
//找到堆的最后一个分支
int curpose = n / 2 - 1 + left;
while (curpose >= left)
{
//向下调整
_AdjustDownByHeapSort(ar, left, right, curpose);
curpose--;
}
//排序
for (int i = right-1; i >left; i--)
{
Swap(&ar[left], &ar[i]);
_AdjustDownByHeapSort(ar, left, i-1, left);
}
}
//交换排序
//冒泡排序_1
void BubbleSort(int* ar, int left, int right)
{
for (int i = left; i < right; i++)
{
for (int j =left; j < right - i - 1; j++)
{
if (ar[j] > ar[j+1])
{
int tmp = ar[j];
ar[j] = ar[j + 1];
ar[j + 1] = tmp;
}
}
}
}
//快速排序 - 挖坑法
//找分点
int _Parttition_1(int* ar, int left, int right)
{
int low = left;
int high = right - 1;
int tmp = ar[low];
while (low<high)
{
while (low<high && ar[high] >= tmp)
high--;
ar[low] = ar[high];
while (low < high && ar[low] < tmp)
low++;
ar[high] = ar[low];
}
ar[low] = tmp;
return low;
}
//快速排序 - 前后指针法
int _Parttition_2(int* ar, int left, int right)
{
int tmp = ar[left];
int next = left;
for (int prev = next+1; prev < right; prev++)
{
if (ar[prev] < tmp)
{
next++;
if (next != prev)
Swap(&ar[prev], &ar[next]);
}
}
Swap(&ar[left], &ar[next]);
return next;
}
//快速排序 - [三者取中]
//将数组最左边,中间,最右边的值进行比较,取中间值。
int GetMidIndex(int* ar, int left, int right)
{
int index = 0;
int n = (right + left - 1) / 2;
if (ar[left]<ar[n] && ar[right]>ar[n])
index = n;
else if (ar[n]<ar[left] && ar[right]>ar[left])
index = left;
else
index = right - 1;;
return index;
}
//找分点
int _Parttition_3(int* ar, int left, int right)
{
//三者取中
int mid = GetMidIndex(ar, left, right);
if (mid != left)
Swap(&ar[mid], &ar[left]);
int tmp = ar[left];
int next = left;
for (int prev = next + 1; prev < right; ++prev)
{
if (ar[prev] < tmp)
{
next++;
if (next != prev)
Swap(&ar[next], &ar[prev]);
}
}
Swap(&ar[left], &ar[next]);
return next;
}
//递归对分点两边分别进行排序
//在排序的元素数小于20时可以使用直接插入进行排序
void QuickSort_1(int* ar, int left, int right)
{
if (left >= right)
return;
//int pos = _Parttition_1(ar, left, right);
//int pos = _Parttition_2(ar, left, right);
int pos = _Parttition_3(ar, left, right);
QuickSort_1(ar, left, pos);
QuickSort_1(ar, pos + 1, right);
}
//归并排序
void _MergeSort(int* ar, int left, int right, int* tmp)
{
//结束条件
if (left >= right)
return;
//递归二分
int mid = (left + right) / 2;
_MergeSort(ar, left, mid, tmp);
_MergeSort(ar, mid + 1, right , tmp);
//重新归并
int b1 = left, e1 = mid, b2 = mid + 1, e2 = right ,k=left;
while (b1 <= e1 && b2 <= e2)
{
if (ar[b1] < ar[b2])
tmp[k++] = ar[b1++];
else
tmp[k++] = ar[b2++];
}
while (b1 <= e1)
tmp[k++] = ar[b1++];
while (b2 <= e2)
tmp[k++] = ar[b2++];
//将数组tmp中的数据放回ar中
memcpy(ar + left, tmp + left, sizeof(int) * (right - left + 1));
}
//归并排序
void MergeSort(int* ar, int left, int right)
{
int n = right - left;
int* tmp = (int*)malloc(sizeof(int)*n);
_MergeSort(ar, left, right-1, tmp);
free(tmp);
tmp = NULL;
}