1.直接插入排序
插入排序的基本思想 : 有一个有序区间,插入一个数据,依旧有序 代码
void InserSort(int* a, int sz)
{
for (int i = 0; i < sz-1; i++)
{
int end = i;
int tmp = a[end + 1];
while (end >= 0)
{
if (tmp < a[end])
{
a[end + 1] = a[end];
end--;
}
else
{
break;
}
}
a[end + 1] = tmp;
}
}
2.希尔排序
思路: 和直接插入排序差不多但是多了个预排序 预排序就是让大的数更快到后面,小的数更快到前面 代码
void ShellSort(int* a, int sz)
{
int gap = sz;
while (gap > 1)
{
gap = gap / 3+1;
for (int i = 0; i < sz-gap; i++)
{
int end = i;
int tmp = a[end + gap];
while (end >= 0)
{
if (tmp < a[end])
{
a[end + gap] = a[end];
end -= gap;
}
else
{
break;
}
}
a[end + gap] = tmp;
}
}
}
3.快排
快排有很多变种
1.hoare
这是快排最开始的一种 思路: 让右边找比key小,左边找key大,找到就交换,如果它们相遇就把相遇的位置和key交换,但是这样有个问题就是怎么保证最后交换的值有序 左边做key,右边先走,右边做key左边先走 右边做key也是一样的 代码
int PartSort1(int* a, int left, int right)
{
int key = left;
while (left < right)
{
if (left < right && a[right] >= a[key])
{
right--;
}
if (left < right && a[left] <= a[key])
{
left++;
}
swap(&a[left], &a[right]);
}
swap(&a[key], &a[right]);
return left;
}
void QuickSort1(int* a, int begin, int end)
{
if (begin >= end)
{
return;
}
int key = PartSort1(a, begin, end);
QuickSort1(a, begin, key - 1);
QuickSort1(a, key + 1, end);
}
2.挖坑法
思路: 存key的值,右边找小,找到右边的值赋给坑位,再把右边的位置变为坑,左边找大找到把左边的值给坑位,再把左边的位置变为坑 //左边和右边相遇的格子是坑位,把key的值赋给坑位
代码
/挖坑法
int PartSort2(int* a, int left,int right)
{
int key = a[left];
int pit = left;
while (left<right)
{
while(left < right && a[right] >= key)
{
right--;
}
a[pit] = a[right];
pit = right;
while(left < right && a[left] <= key)
{
left++;
}
a[pit] = a[left];
pit = left;
}
a[pit] = key;
return pit;
}
3.前后指针法
思路: cur找到比key小的值和prev交换再把prev++,cur循环结束把key和prev交换 代码
int PartSort3(int* a, int left, int right)
{
int mid = GetMidIndex(a, left, right);
swap(&a[left], &a[mid]);
int key = left;
int cur = left + 1;
int prev = left;
while (cur <= right)
{
if (a[cur] <= a[key] && a[prev++] != a[cur])
{
swap(&a[cur], &a[prev]);
}
cur++;
}
swap(&a[key], &a[prev]);
return prev;
}
void QuickSort1(int* a, int begin, int end)
{
if (begin >= end)
{
return;
}
int key = PartSort3(a, begin, end);
QuickSort1(a, begin, key - 1);
QuickSort1(a, key + 1, end);
}
4.非递归快排
思路: 用栈来模拟递归遍历整个数组 代码
void QuickSort3(int* a, int left, int right)
{
ST st;
StackInit(&st);
StackPush(&st, left);
StackPush(&st, right);
while (!StackEmpty(&st))
{
int right = StackTop(&st);
StackPop(&st);
int left = StackTop(&st);
StackPop(&st);
int key = PartSort2(a, left, right);
if (left < key - 1)
{
StackPush(&st, left);
StackPush(&st, key-1);
}
if (key + 1 < right)
{
StackPush(&st, key+1);
StackPush(&st, right);
}
}
StackDestory(&st);
}
|