利用交换元素的位置进行排序的方法称作交换排序
常用的交换排序的方法:冒泡排序和快速排序
【冒泡排序】
冒泡排序最好情况时间复杂度O(n),冒泡排序最坏情况下时间复杂度O(n^2)
冒泡排序空间复杂度O(1)
冒泡排序是一种稳定的排序算法
void BubbleSort(int* array, int size)
{
int i = 0;
for (i = 0; i < size; i++)
{
int j = 0;
for (j = 0; j < size - 1 -i; j++)
{
if (array[j] > array[j + 1])
Swap(&array[j], &array[j + 1]);
}
}
}
交换函数
void Swap(int* pLeft, int* pRight)
{
int tmp;
assert(pLeft);
assert(pRight);
tmp = *pLeft;
*pLeft = *pRight;
*pRight = tmp;
}
【快速排序】
快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基
本思想为:任取待排序元素序列中的某元素作为基准值,按照该排序码将
待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右子序
列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元
素都排列在相应位置上为止。
将区间按照基准值划分为左右两半部分的常见方式有:
hoare版本
挖坑法
前后指针
快排的时间复杂度:O(N*log2N)
快排的空间复杂度: O(log2N) (单支为O(N))
快排是不稳定的
快排递归代码
void QuickSort(int* array, int left,int right)
{
if (right - left > 1)
{
int div = Partion3(array, left, right);
QuickSort(array, left, div);
QuickSort(array,div+1,right);
}
}
hoare法
int Partion1(int* array, int left, int right)
{
int begin = left;
int end = right - 1;
int key = array[end];
while (begin < end)
{
//从前往后找比基准值大的元素
while (begin < end && array[begin] <= key)
++begin;
//从后往前找比基准值小的元素
while (begin < end && array[end] >= key)
--end;
if (begin < end)
Swap(&array[begin], &array[end]);
}
if (begin != right)
Swap(&array[begin], &array[right - 1]);
return begin;
}
挖坑法
int Partion2(int* array, int left, int right)
{
int begin = left;
int end = right - 1;
//将基准值保存在key里面,原来基准值所在的位置会出现一个坑
int key = array[end];
while (begin < end)
{
//从前往后找比基准值大的元素
while (begin < end && array[begin] <= key)
++begin;
//找到比基准值大的元素后就用该值去填充上次的坑
if (begin < end)
{
array[end] = array[begin];
end--;
}
//从后往前找比基准值小的元素
while (begin < end && array[end] >= key)
--end;
//找到比基准值小的元素后就用该值去填充上次的坑
if (begin < end)
{
array[begin] = array[end];
begin++;
}
}
//用基准值来填充最后一个坑
array[begin] = key;
return begin;
}
前后指针
int Partion3(int* array, int left, int right)
{
int pre = left - 1;
int cur = left;
int key = array[right - 1];
while (cur < right)
{
if (array[cur] < key && ++pre != cur)
Swap(&array[cur], &array[pre]);
++cur;
}
if (++pre != right)
Swap(&array[pre], &array[right - 1]);
return pre;
}
快排非递归代码
void QuickSortNor(int* array, int size)
{
if (size < 1)
return;
Stack s;
StackInit(&s);
//右边元素先入栈
StackPush(&s, size);
StackPush(&s, 0);
while (!StackEmpty(&s))
{
int left = 0;
int right = 0;
//取栈顶元素即为左边元素
left = StackTop(&s);
StackPop(&s);
right = StackTop(&s);
StackPop(&s);
if (left < right)
{
int div = Partion1(array, left, right);
//左半部分元素先入栈
StackPush(&s, right);
StackPush(&s,div + 1);
StackPush(&s,div);
StackPush(&s, left);
}
}
}