这是我的第一篇博客,如果本文有任何错误,欢迎提出并指正,以下介绍并比较了两个排序算法——冒泡排序和快速排序的基本思想以及代码解释。
冒泡排序
原理:
冒泡排序算法的原理基于不断地比较相邻的元素并交换它们的位置,直到整个数组按照升序或降序排列完成。下面是冒泡排序算法的基本操作步骤:
-
比较相邻元素: 从数组的第一个元素开始,依次比较相邻的两个元素,例如
a[i]
和a[i+1]
。 -
交换位置: 如果前面的元素大于后面的元素(升序排序),则交换它们的位置;如果前面的元素小于后面的元素(降序排序),则不进行交换。
-
一轮比较完成: 经过一轮的比较和可能的交换操作之后,最大(或最小)的元素被“冒泡”到了数组的末尾。
-
重复步骤1~3: 除了已经排好序的元素外,重复进行上述比较和交换的步骤,直到整个数组排序完成。
在每一轮的排序中,通过不断地比较和交换相邻元素的位置,较大(或较小)的元素会逐渐“浮”到数组的顶端或底端,完成一次排序。这样经过多次的遍历和交换之后,整个数组就能够完成排序。
冒泡排序算法的关键点在于内循环中的比较和交换操作,以及外循环的重复迭代,直到整个数组排序完成。
平均时间复杂度:n2
代码展示:
#include <stdio.h>
int main()
{
int n= 0;
scanf("%d", &n);//给出数组长度
int arr[30] = { 0 };//初始化数组
for (int i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}//输入数组元素
for (int i = 0; i < n - 1; i++)//冒泡排序趟数
{
int t = 0;
for (int j = 0; j < n - 1 - i; j++)//冒泡排序比较次数
{
if (arr[j] < arr[j + 1])//大的和小的交换,实现"冒泡"
{
t = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = t;
}
}
}
for (int i = 0; i < n; i++)
{
printf("%d\n",arr[i]);
}//输出数组经过冒泡排序后从大到小的顺序
return 0;
}
快速排序
原理:
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据比另一部分的所有数据要小,再按这种方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,使整个数据变成有序序列。
-
选择基准值: 从数组中选择一个基准值(pivot),通常选择数组第一个元素。
-
分区过程: 将数组中的元素分为两部分,使得左边的元素都小于基准值,右边的元素都大于基准值。具体做法是设置两个指针,一个指向数组的起始位置,一个指向数组的末尾,然后它们向中间移动,直到两个指针相遇。在移动的过程中,如果发现左边的元素大于基准值且右边的元素小于基准值,则交换这两个元素。
-
递归排序: 对基准值左右两边的子数组分别进行快速排序。
-
合并结果: 左右两边的子数组都排好序之后,整个数组也就排好序了。
平均时间复杂度:nlogn
代码展示:
#include <stdio.h>
// 快速排序函数,对数组a中从下标left到下标right的元素进行排序
int a[100];
void quicksort(int left, int right)
{
int i, j, t, temp;
// 如果左边界大于右边界,表示已经完成排序或数组为空,直接返回
if (left > right)
return;
// 选取最左边的元素作为基准值
temp = a[left];
i = left;
j = right;
// 开始进行分区操作
while (i != j)
{
// 从右边开始,找到第一个小于基准值的元素
while (a[j] >= temp && i < j)
{
j--;
}
// 从左边开始,找到第一个大于基准值的元素
while (a[i] <= temp && i < j)
{
i++;
}
// 交换这两个元素的位置
if (i < j)
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
}
// 将基准值放到正确的位置
a[left] = a[i];
a[i] = temp;
// 对基准值左右两边的子数组进行递归排序
quicksort(left, i - 1);
quicksort(i + 1, right);
}
//主函数部分
int main()
{
int n, i;
scanf("%d", &n);
//输入数组长度
for (i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
//依次输入数组元素
quicksort(0, n - 1);//调用快速排序函数
for (i = 0; i < n; i++)
{
printf("%d\n", a[i]);
}
//按照从小到大的顺序输出数组元素
return 0;
}
两种算法对比
冒泡排序和快速排序是两种常见的排序算法,它们在实现方式、效率和适用场景上有很大的不同。
-
实现方式:
- 冒泡排序:通过比较相邻的元素并交换,依次将最大(或最小)的元素“冒泡”到顶端。
- 快速排序:通过选择一个基准值,将序列分割成两部分,左边部分的元素都小于等于基准值,右边部分的元素都大于等于基准值,然后对左右部分分别递归进行排序。
-
效率:
- 冒泡排序的平均时间复杂度为O(n^2),最好情况下是O(n),最坏情况下是O(n^2)。
- 快速排序的平均时间复杂度为O(nlogn),最坏情况下是O(n^2)。
-
稳定性:
- 冒泡排序是稳定的排序算法,相等元素的相对位置不会改变。
- 快速排序是不稳定的排序算法,相等元素的相对位置可能会改变。
-
适用场景:
- 冒泡排序适合于简单的排序需求和小规模数据,由于效率较低,一般不适用于大规模数据的排序。
- 快速排序适用于大规模数据和对效率要求较高的排序场景,在实践中通常比其他排序算法更快。
总体来说,快速排序比冒泡排序更加高效,尤其在处理大规模数据时表现更为突出。然而,冒泡排序的实现相对更加简单直观。在实际应用中,根据具体的排序需求和数据规模选择合适的排序算法是非常重要的。