初学者的第一次算法(排序)

33 阅读3分钟

我人生中第一次接触算法是在课本上看到的冒泡排序,这是我第一次叩开算法的大门,排序应该是所有初学者最先接触到的算法,他也是很多高级算法必不可少的一部分,今天介绍一些适合初学者学习的排序算法。

冒泡排序

for (int i = 0; i < n - 1; i++)          // 外层控制趟数
    {
        for (int j = 0; j < n - 1 - i; j++)  // 每趟把最大值“冒”到最后
        {
            if (a[j] > a[j + 1])
            {
                swap(a[j], a[j + 1]);
            }
        }
    }

首先,单论这个算法,在排序里并不算效率高的,但确实很适合初学者了解算法思想。如果大家不理解这个算法死记硬背也是可以的,因为这个算法没什么变化,多敲几遍自然会理解了,下面讲一下这个算法的原理:

冒泡核心在于交换
5 3 8 4

我们做的事情只有一件: 两两比较
如果前面大,就交换 (5比3大所以3就要放前面)

好了到这其实你已经完全掌握冒泡了,借下来演示一下里面的遍历过程

假设数组里依旧5384。。。。

第一趟过程

原数组:

5 3 8 4
第1步

比较 5 和 3
5 > 3 → 交换

3 5 8 4
第2步

比较 5 和 8
5 < 8 → 不动

3 5 8 4
第3步

比较 8 和 4
8 > 4 → 交换

3 5 4 8

第一趟结束后:

最大的数 8 已经到最后了

3 5 4 | 8

比较:

  • 3 和 5 → 不动
  • 5 和 4 → 交换

变成:

3 4 5 8

第二趟结束后:

第二大的数 5 到了倒数第二


第三趟
3 4 | 5 8
  • 3 和 4 → 不动

规律就是

  • 第一趟比较 n-1 次

  • 第二趟比较 n-2 次

  • 第三趟比较 n-3 次

    这就是n-i-1的来历

ok,这个算法不难在于大家弄两个数组自己画一画理解理解,当然这个算法是可以优化的这里不赘叙,因为效率低,只了解思想即可。

快速排序

void quick_sort(int q[], int l, int r)
{
   if (l >= r) return;

   int i = l, j = r;
   int x = q[(l + r) >> 1];   // 中间值

   while (i <= j)
   {
       while (q[i] < x) i++;
       while (q[j] > x) j--;

       if (i <= j)
       {
           swap(q[i], q[j]);
           i++;
           j--;
       }
   }

   if (l < j) quick_sort(q, l, j);
   if (i < r) quick_sort(q, i, r);
}

解释:q是要求的数据,lr分别为左右指针,x是数据的中心位置。

思想:分治

快速排序的结构:

  1. 选择一个基准值(pivot)
  2. 把数组按 pivot 分成两部分
  3. 递归排序左右两部分

可以理解为:

        [整个数组]
             ↓
      选 pivot 分裂
       /           \
  左区间         右区间

这就是典型的 分治思想

展示一轮递归
第一次循环

① while(q[i] < 4)

q[0] = 5
5 < 4

i 不动 → i=0


② while(q[j] > 4)

q[4] = 3
3 > 4

j 不动 → j=4


③ i <= j → 0 <= 4

交换 q[0] 和 q[4]

3 1 4 2 5

然后:

i = 1
j = 3

第二次循环

现在数组:

3 1 4 2 5

i=1
j=3


① while(q[i] < 4)
q[1] = 1 < 4  → i=2
q[2] = 4 < 4 //不符合

停在 i=2


② while(q[j] > 4)
q[3] = 2
2 > 4 

j 还是 3


③ i <= j → 2 <= 3

交换 q[2] 和 q[3]

3 1 2 4 5

然后:

i = 3
j = 2

第三次判断

i <= j ?
3 <= 2 //不符合哦哦哦哦哦哦吼吼吼吼

循环结束。


最终分区结果
3 1 2 4 5

哈哈,接下来就进入递归了。

你会发现他是在找中间值,然后小于中间值的仍左边,大于扔右边

微信图片_20260215021125_13_85.jpg

哈哈哈弄倒了,那就倒者看吧呜呜呜呜。。。 ok,排序的效率是比冒泡高的,这些算是一种底层,大多数直接sort(底层:快速排序 + 堆排序 + 插入排序)了。。 累了,选择和归并下一个发吧啊啊啊啊。。。