冒泡排序
思想:
(1)将相邻的两个数 Ai 和 A(i+1) 进行比较,如果 A(i+1) 较大,则交换 Ai 和 A(i+1) ;
(2)如果 Ai 较大,则不交换;
(3)每次排序后都将未排序好的最大的数冒到指定位置。
时间复杂度:O(N^2)
每次排序结果:
代码:
void bubble_sort(int* a, int n)
{
int flag = 0;
for (int i = 0; i < n-1; i++)
{
for (int j = 0; j < n-i-1; j++)
{
if (a[j] > a[j + 1])
{
swap(a[j], a[j + 1]);
flag = 1;
}
}
if (flag == 0)
break;
}
}
选择排序
思想:
(1)对数组设置begin和end,也就是第一个元素和最后一个元素的下标;
(2)遍历一遍数组找最大值的下标max和最小值下标min;
(3)将找到的最大值max和end的值进行交换,最小值min和begin的值进行交换;
(4)此时最大值和最小值已经位于最终的位置上;
(5)之后将begin++,end–,调整数组区间,继续进行上述的过程。
时间复杂度:O(N^2)
每次排序结果:
代码:
void select_sort(int* a, int n)
{
//从两端缩小范围
int begin = 0;
int end = n - 1;
while (begin < end)
{
int max = begin;
int min = end;
for (int i = begin; i <= end; i++)
{
if (a[max] < a[i])
max = i;
if (a[min] > a[i])
min = i;
}
swap(a[max], a[end]);
//可能在a[max]和a[end]交换之后,找不到a[min]的值
if (min == end)
{
min = max;
}
swap(a[min], a[begin]);
++begin;
--end;
}
}
快速排序
思想:以数组最右端的数为key值为例
(1)设置begin为A[0],end为A[n],key = A[n];
(2)从begin开始向后找比key大的值,从end开始向前查找比key小的值;
(3)找到后,将A[begin]和A[end]的值交换,之后begin++,end–;
(4)直至begin和end相遇,将 key 值与 A[end] 交换,此次快排结束,一次快排之后可以保证key前面的数一定以key小,key后面的数一定比key大;
(5)将整个数组分为两部分:key值之前,key值之后,再次进行上述操作…;
(6)直至begin和end的区间内之后一个数,表明排序结束。
时间复杂度:最好O(N*logN) 平均:O(N^2)
每次排序结果:
代码:
int _quick_sort (int* a, size_t left, size_t right)
{
size_t begin = left;
size_t end = right;
int key = a[right];
while (begin < end)
{
while (begin < end && a[begin] <= key)
++begin;
while (begin < end && a[end] >= key)
--end;
swap(a[begin], a[end]);
}
swap(a[begin], a[right]);
return begin;
}
void quick_sort(int* a, int left,int right)
{
assert(a);
if (left >= right)
return;
else
{
int div =_quick_sort (a, left, right);
quick_sort(a, left, div - 1);
quick_sort(a, div + 1, right);
}
}
归并排序
思想:
(1)对于已经排序完成的两个子数组,按顺序进行合并;
(2)合并时首先开辟一个与数组大小相同的新数组tmp,选择两个数组中较小的数值放在数组tmp中;
(3)遍历两个子数组,依次放置在tmp中,此时tmp中为已经排序完成的数组;
(4)将tmp中的内容,替换原数组;
每次排序结果:
代码:
void _mergesort(int* a, int left, int right, int* tmp)
{
if (left >= right)
return;
int mid = left + ((right - left) >> 1);
_mergesort(a, left, mid, tmp);
_mergesort(a, mid + 1, right, tmp);
int begin1 = left;
int end1 = mid;
int begin2 = mid + 1;
int end2 = right;
int i = 0;
while (begin1 <= end1 && begin2 <= end2)
{
if (a[begin1] <= a[begin2])
{
tmp[i] = a[begin1];
begin1++;
}
else
{
tmp[i] = a[begin2];
begin2++;
}
i++;
}
if (begin1 <= end1)
{
tmp[i] = a[begin1];
begin1++;
i++;
}
else if (begin2 <= end2)
{
tmp[i] = a[begin2];
begin2++;
i++;
}
for (int j = 0; j < i; j++)
{
a[j+left] = tmp[j];
}
}
void merge_sort(int* a, int left,int right)
{
assert(a);
if (left >= right)
return;
int* tmp = new int[right - left + 1];
_mergesort(a, left, right, tmp);
}