1--快速排序:
快排原理:
-
选基准:从数组中选一个元素作为基准(比如第一个元素)。
-
分区:重新排列数组,比基准小的放左边,比基准大的放右边,基准自身位于中间正确的位置。
具体操作:用两个指针扫描数组,交换不符合条件的元素,直到所有元素与基准比较完毕。 -
递归:对基准左右两边的子数组重复上述步骤,直到所有元素有序。
简单概括:像“快速分类”,每次确定一个元素的最终位置,再处理剩下的两部分,直到全部排好。
int a[] = { 3,2,4,1,5,7,9,6,8 };
void swap(int& a, int& b) {
int temp = a;
a = b;
b = temp;
}
void quick(int* a ,int start,int end) {
//base记录的是左边的位置,一定要从右边开始遍历,把l替换掉,
// 如果从左边 开始走的话,吧右边的值给替换掉了,因为没有记录,而造成数据丢失
// 递归一定不要掉了结束条件,要不然递归没法结束!!!
//下面的while的循环条件一定不要掉了l<r;要不然会走过来造成l>r;最外层的循环结束时候
//一定要是l==r;
if (start < end) {
int l = start;
int r = end;
int base = a[start];
while (r > l) {
while (a[r] >= base && l < r) {
r--;
}
a[l] = a[r];
while (a[l] <= base && l < r) {
l++;
}
a[r] = a[l];
}
a[r] = base;
quick(a, start, l - 1);
quick(a, r + 1, end);
}
}
//最好情况下的时间复杂度O(nlog(n)),最坏的情况下时间复杂度为O(n~2).
quick(a, 0, 8);
//运行结果1 2 3 4 5 6 7 8 9
2--冒泡排序:
冒泡原理:
-
相邻交换:从头开始比较相邻元素,如果顺序错误(如左 > 右),就交换它们。
-
多轮遍历:每轮遍历会将当前最大元素“冒泡”到末尾,重复直到全部有序。
特点:效率低(时间复杂度 O(n²)),但实现简单。
概括:反复交换相邻元素 → 大值上浮。
//接下来巩固一下最基本的两种排序算法(algorithm),冒泡排序和选择排序。
void maopao(int* a, int size) {
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - 1 - i; j++) {
if (a[j] > a[j + 1]) {
swap(a[j], a[j + 1]);
}
}
}
}
//冒泡排序实际上是一种交换排序,每次排序都把未排序中的最大元素排到最后面
//如果一趟下来没有进行交换说明,序列已经是有序的,就可以停止排序
//因此我们可以设置一个标志位flag来记录每趟是否发生了交换,如果没有发生交换就break;
void maopaonew(int* a, int size) {
bool flag;
for (int i = 0; i < size - 1; i++) {
flag = false;
for (int j = 0; j < size - 1 - i; j++) {
if (a[j] > a[j + 1]) {
swap(a[j], a[j + 1]);
flag = true;
}
}
if (flag == false)
break;
}
}
3--选择排序:
选择原理:
-
找最小:每轮遍历找到未排序部分的最小值。
-
交换位置:将最小值交换到已排序部分的末尾(即当前位置)。
特点:时间复杂度 O(n²),但交换次数少于冒泡排序。
概括: 每轮选最小 → 直接定位。
//选择排序
void xuanze(int* a, int size) {
int minindex;
for (int i = 0; i < size - 1; i++) {
minindex = i;
for (int j = i + 1; j < size; j++) {
if (a[j] < a[minindex]) {
minindex = j;
}
}
swap(a[i], a[minindex]);
}
}
4--插入排序
插入原理:
-
分区域:将数组分为已排序区(初始仅第一个元素)和未排序区。
-
插入元素:逐个将未排序区的元素插入已排序区的正确位置(像理扑克牌)。
特点:时间复杂度 O(n²),但对接近有序的数据效率高。
概括:逐个元素插入 → 适合小规模或局部有序数据。
/接下来,我们再写一下,插入排序,先讲一下思想,要跟前面两种排序进行区分一下
//就是把序列分成两部分:未排序的序列和已排序的序列
//刚开始已排序的序列个数为未排序序列中的第一个元素
//不断的循环将未排序的元素逐一插入到已排序序列中合适的位置使其仍然保持有序
//废话不多说我们直接开始写代码
void charu(int* a, int size) {
int i, j;
for (i = 1; i < size ; i++) {
int temp = a[i];
for (j = i-1; j >=0; j--) {
if (a[j] > temp) {
a[j+1] = a[j];
}
else
{
break;
}
}
a[j+1] = temp;
}
}
目前这几种排序已经够用了
另外还有几种效率更高的排序方式(堆排序,归并,桶排序,基数排序,希尔排序。。。。。),作者后续持续更新!!!
六百六十六,能不能点个关注😀