交换排序的基本思想:两两比较待排序记录的关键码,如果发生逆序(即排列顺序与排序后的次序正好相反),则交换之,直到所有记录都排好序为止。
其中主要包括两种算法
1、冒泡排序
相邻的元素两两比较,较大的数下沉,较小的数冒起来,这样一趟比较下来,最大(小)值就会排列在一端。整个过程如同气泡冒起,因此被称作冒泡排序。
//交换排序的算法
//1、冒泡排序,传入指针后在修改指向内容,再返回时会被修改
void BubbleSort(int* a, int n)
{
for (int i=0; i < n - 1; i++)//n个数比较n-1次,总共比较n-1次
{
for (int j=0; j < n - i - 1; j++)//每次比较n-i-1的左右大小判断是否交换
{
if (a[j] > a[j + 1])
{
int temp = a[j];
a[j] = a[j+1];
a[j + 1] = temp;
}
}
}
}
2、快速排序
通过一趟排序将待排序列以枢轴为标准划分成两部分,使其中一部分记录的关键字均比另一部分小,再分别对这两部分进行快速排序,以达到整个序列有序。
通常取第一个记录的值为基准值或枢轴。
//2、快速排序
//一趟快速排序的描述,取一个枢纽,排序好比它小的左边,大的右边,并且返回这个值的指针
int QStep(int* a, int low, int high)
{
int temp = a[low];//temp作为枢纽
while (low < high)
{
while (low < high && temp <= a[high])
{
high--;
}
a[low] = a[high];
while (low < high && temp >= a[low])
{
low++;
}
a[high] = a[low];
}
a[low] = temp;
return low;
}
//对于全部排好则要进行递归
void QSort(int* a, int low, int high)
{
if (low < high)//长度大于1
{
int mid = QStep(a, low, high);
QSort(a, low, mid - 1);
QSort(a, mid + 1, high);
}
}
//封装成传递指针和元素个数的函数
void QuickSort(int* a, int n)
{
QSort(a, 0, n - 1);
}
基于这种思想完成的算法,用来排序好一个数组。
2022/5/3加入继续分析
快速排序分析
时间复杂度: O(n logn),因为一个枢纽可以把两边元素整合到枢纽的左右,一次调用分出两块,
第一次调用函数确定1个数的位置,然后2,4,8,指数型确定
空间复杂度:O(log2 n) ,这个算法有递归性,需要用到栈区空间。
稳定性:稳定性差,如果开始时乱序比较快速,如果每次枢纽都是中位数,那么速度最快。(最好情况) 如果已经排序好,那么就要和后面的全部比较,此时速度最慢。(最坏情况)