【数据结构常见七大排序(三)上】—交换排序篇【冒泡排序】And【快速排序】

简介: 【数据结构常见七大排序(三)上】—交换排序篇【冒泡排序】And【快速排序】

前言


交换类排序两个常见的排序算法【冒泡排序】、【快速排序】

交换排序基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置。

交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。

1.冒泡排序


1.1冒泡排序动图

冒泡排序动图

1.2冒泡排序源代码

void BubbleSort(int* a, int n)
{
  assert(a);
 
  for (int j = 0; j < n - 1; ++j)
  {
    int exchange = 0;//这里的exchange的值作为是否交换的标志
    for (int i = 1; i < n - j; ++i)
    {
      if (a[i - 1] > a[i])
      {
        Swap(&a[i - 1], &a[i]);
        exchange = 1;
      }
    }
 
    if (exchange == 0)//一趟下来exchange的值还为0,证明就没有发生交换,也就是已经有序
    {
      break;
    }
  }
}

1.3冒泡排序的特性总结

1. 冒泡排序是一种非常容易理解的排序

2. 时间复杂度: O(N^2)   最坏O(N^) 、最好O(N)

3. 空间复杂度: O(1)

4. 稳定性:稳定


2.快速排序👑


快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法。

其基本思想为: 任取待排序元素序列中 的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子序列中所有元素均小于基准值,右 子序列中所有元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止


2.1hoare版本实现思想

排序前


排序中

①先选出一个基准值key(一般是最左边或者最右边)

②然后右边【L】先走找比key小的值,找到了就停下,然后再左边找比key大的值,找到了也停下

③然后交换这两个数

经过上面三步,就动图就变成了下面的样子

🥇

🥈


排序后

由于是一个一个先走一个后走,肯定会出现相遇的时候,相遇就停下来。相遇后将相遇坐标的值和基准值key交换,这时就完成了单趟的hoare排序

【这时的key其实就是在正确的位置上了】

相遇时如下图

🥉

2.2hoare版本快排源代码

void QuickSort(int* a, int begin, int end)
{
  // 区间不存在,或者只有一个值则不需要在处理
  if (begin >= end)
  {
    return;
  }
 
  int left = begin, right = end;
  int keyi = left;
  while (left < right)
  {
    // 右边先走,找小
    while (left < right && a[right] >= a[keyi])
    {
      --right;
    }
 
    // 左边再走,找大
    while (left < right && a[left] <= a[keyi])
    {
      ++left;
    }
 
    Swap(&a[left], &a[right]);
  }
 
  Swap(&a[keyi], &a[left]);
  keyi = left;
 
  // [begin, keyi-1] keyi [keyi+1, end]
  QuickSort(a, begin, keyi - 1);
  QuickSort(a, keyi+1, end);
}


2.3分析先走

为什么左边做key,右边先走。

右边做key,左边先走。

这样就可以保证相遇位置的值小余或者等于key

我这边拿左边做key,右边先走的情况来讲解。

情况1🥇

这个情况比较好理解,就是上面最后相遇位置的值,也就是3,比6要小

情况2🥈

这个情况如下图所示

这边也可以去画一下左边做key,左边先走的情况,会发现相遇位置的值不能保证比key要小


相关文章
|
2月前
|
算法 搜索推荐 Shell
数据结构与算法学习十二:希尔排序、快速排序(递归、好理解)、归并排序(递归、难理解)
这篇文章介绍了希尔排序、快速排序和归并排序三种排序算法的基本概念、实现思路、代码实现及其测试结果。
32 1
|
2月前
|
算法 搜索推荐 Java
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
基数排序是一种稳定的排序算法,通过将数字按位数切割并分配到不同的桶中,以空间换时间的方式实现快速排序,但占用内存较大,不适合含有负数的数组。
38 0
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
|
2月前
|
存储 搜索推荐 算法
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
29 1
|
2月前
|
算法
蓝桥杯宝藏排序 | 数据结构 | 快速排序 归并排序
蓝桥杯宝藏排序 | 数据结构 | 快速排序 归并排序
|
1月前
|
C语言
【数据结构】栈和队列(c语言实现)(附源码)
本文介绍了栈和队列两种数据结构。栈是一种只能在一端进行插入和删除操作的线性表,遵循“先进后出”原则;队列则在一端插入、另一端删除,遵循“先进先出”原则。文章详细讲解了栈和队列的结构定义、方法声明及实现,并提供了完整的代码示例。栈和队列在实际应用中非常广泛,如二叉树的层序遍历和快速排序的非递归实现等。
178 9
|
1月前
|
存储 算法
非递归实现后序遍历时,如何避免栈溢出?
后序遍历的递归实现和非递归实现各有优缺点,在实际应用中需要根据具体的问题需求、二叉树的特点以及性能和空间的限制等因素来选择合适的实现方式。
32 1
|
23天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
44 5
|
1月前
|
存储 算法 Java
数据结构的栈
栈作为一种简单而高效的数据结构,在计算机科学和软件开发中有着广泛的应用。通过合理地使用栈,可以有效地解决许多与数据存储和操作相关的问题。
|
1月前
|
存储 JavaScript 前端开发
执行上下文和执行栈
执行上下文是JavaScript运行代码时的环境,每个执行上下文都有自己的变量对象、作用域链和this值。执行栈用于管理函数调用,每当调用一个函数,就会在栈中添加一个新的执行上下文。
|
1月前
|
存储
系统调用处理程序在内核栈中保存了哪些上下文信息?
【10月更文挑战第29天】系统调用处理程序在内核栈中保存的这些上下文信息对于保证系统调用的正确执行和用户程序的正常恢复至关重要。通过准确地保存和恢复这些信息,操作系统能够实现用户模式和内核模式之间的无缝切换,为用户程序提供稳定、可靠的系统服务。
51 4